Python Forum
Sending data from a websocket client to another server - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html)
+--- Thread: Sending data from a websocket client to another server (/thread-27019.html)



Sending data from a websocket client to another server - lemon - May-22-2020

Hello,

I'm stuck with a problem that I try to solve since a few days... Huh

I'm a beginner at programming server/client networks.
I want to build a web application facilitating the following workflow:

1) receive and then process realtime data from a server via WebSocket API (python client)
2) send the processed data from the python client to another websocket server (python tornado)
3) send the data from the tornado websocket server to a javascript websocket client
4) presenting the data on a website

Everything works except for step 2. I have no idea how I can send data from a client to another server.
Maybe I have a fundamental misconception about how to build these kind of networks.
I post my code below so that you can have a glance at it.

I would highly appreciate if someone could shed some light on this! Smile

Thanks and cheers!
lemon

[Image: websocket.png]


Python websocket client
from threading import Timer
import websocket


class WebsocketClient:
    def connect(self, wsURL="ws://echo.websocket.org"):
        self.__connect(wsURL)
    
    def closeWebsocket(self):
        self.ws.close()
        print("Timer end")

    def __connect(self, wsURL):
        self.ws = websocket.WebSocketApp(
            wsURL,
            on_message=self.__on_message,
            on_close=self.__on_close,
            on_open=self.__on_open,
        )
        self.ws.run_forever()

    def __on_open(self):
        print("Websocket opened")
        self.ws.send("Websocket rocks!")

    def __on_message(self, msg):
        print("IN: ", msg)

    def __on_close(self):
        print("Websocket closed")


def startClient():
    ws = WebsocketClient()    
    Timer(2.0, ws.closeWebsocket).start()
    ws.connect()
    print("Finished")
Python Tornado websocket server
import os.path
import tornado.web
import tornado.websocket
import tornado.httpserver
from threading import Timer

class Application(tornado.web.Application): 
    def __init__(self):
        handlers = [
            (r"/", IndexHandler),
            (r"/ws", WsHandler)
            ]
        settings = dict(
            template_path=os.path.join(os.path.dirname(__file__), "template"), 
            static_path=os.path.join(os.path.dirname(__file__), "static"), 
        )
        tornado.web.Application.__init__(self, handlers, **settings)

class IndexHandler(tornado.web.RequestHandler): 
    def get(self):
        self.render("index.html")

class WsHandler(tornado.websocket.WebSocketHandler): 
    def open(self):
        self.write_message('Server CONNECTED')

    def on_message(self, message): 
        print(message)
    
    def on_close(self):
        print('Server DISCONNECTED.')

if __name__ == "__main__": 
    app = Application()
    server = tornado.httpserver.HTTPServer(app) 
    server.listen(8000) 
    tornado.ioloop.IOLoop.instance().start()
JavaScript websocket client
var ws = new WebSocket("ws://localhost:8000/ws");

ws.onopen = function () {
ws.send("Client CONNECTED");
};

ws.onmessage = function (evt) {
document.getElementById("p1").innerHTML = evt.data;
};

ws.onclose = function () {
console.log("Client DISCONNECTED");
};


RE: Sending data from a websocket client to another server - lemon - May-25-2020

I worked out a solution to my problem concerning step 2 and found a new problem! Dance Wall
Now I can send messages from the websocket client to the tornado server. (I have included the updated code below.)
I just transfer a set of websocket connections to the client.
tornado_connections = set()
def __on_message(self, msg):
        [client.write_message(msg) for client in self.connections]
Unfortunately, as soon as I start the websocket client (WsHandler) I can only have 1 client connected to the tornado server. I assume this has something to do with threading/asynchrony. Huh
start_client(connections=tornado_connections)
Has anyone a proposal how to overcome that problem?

Thanks!



Python websocket client

import websocket
 
 
class WebsocketClient:
    def __init__(self, connections):
        self.connections = connections
     
    def __on_open(self):
        print("Websocket opened")
        self.ws.send("Websocket rocks!")
 
    def __on_message(self, msg):
        [client.write_message(msg) for client in self.connections]
 
    def __on_close(self):
        print("Websocket closed")
 
    def connect(self):
        self.ws = websocket.WebSocketApp(
            "ws://echo.websocket.org",
            on_message=self.__on_message,
            on_close=self.__on_close,
            on_open=self.__on_open,
        )
        self.ws.run_forever()

    def disconnect(self):
        self.ws.close()
        print("PYTHON: Timer end")

 
def start_client(connections):
    ws = WebsocketClient(connections=connections)    
    ws.connect()
    print("Finished")
Python tornado websocket server

import os.path
import tornado.web
import tornado.websocket
import tornado.httpserver
from ws_client_test import start_client

tornado_connections = set()

class Application(tornado.web.Application): 
    def __init__(self):
        handlers = [
            (r"/", IndexHandler),
            (r"/ws", WsHandler)
            ]
        settings = dict(
            template_path=os.path.join(os.path.dirname(__file__), "template"), 
            static_path=os.path.join(os.path.dirname(__file__), "static"), 
        )
        tornado.web.Application.__init__(self, handlers, **settings)
 
class IndexHandler(tornado.web.RequestHandler): 
    def get(self):
        self.render("index_test.html")
 
class WsHandler(tornado.websocket.WebSocketHandler): 
    def open(self):
        if self not in tornado_connections:
            tornado_connections.add(self)
            print(f'TORNADO: {str(len(tornado_connections))} clients connected')
            self.write_message(f'TORNADO: {str(len(tornado_connections))} clients connected')
        
        if len(tornado_connections) == 1:
            start_client(connections=tornado_connections)
            print('Echo client connected')
        
 
    def on_message(self, message): 
        print(message)
     
    def on_close(self):
        if self in tornado_connections:
            tornado_connections.remove(self)
            print('TORNADO: server disconnected.')


if __name__ == "__main__": 
    app = Application()
    server = tornado.httpserver.HTTPServer(app) 
    server.listen(8000) 
    tornado.ioloop.IOLoop.instance().start()
JavaScript websocket client
var ws = new WebSocket("ws://127.0.0.1:8000/ws");

ws.onopen = function () {
ws.send("Client CONNECTED");
};

ws.onmessage = function (evt) {
document.getElementById("p1").innerHTML = evt.data;
};

ws.onclose = function () {
console.log("Client DISCONNECTED");
};