Search code examples
javascriptpythonpython-3.xcherrypyws4py

ws4py - send/received_message not working


I'm encountering issues on making a WebSocket Server/Client.

This is my WebSocket Clas:

wslist = []

class LoginLiveWebSocketHandler(WebSocket):  # /live/ws/zones
    loggedon = False

    def opened(self):
        log("Opened!")
        wslist.append(self)

    def received_message(self, m):
        log("Received Message!")
        log(m)
        log(m.data)
        m = str(m.data)
        if not m.startswith("Login: ") & (not self.loggedon):
            return
        if m.startswith("Login: ") & self.loggedon:
            return
        if m.startswith("Login: ") & (not self.loggedon):
            split = m.replace("Login: ", "").split(":")
            try:
                id = split[0]
                key = split[1]
            except KeyError:
                self.send("Login: 0", False)
                return
            try:
                usr = users.getuser(id, key)
                nick = usr["nick"]
                loggedin = True
                token = usr["groupme_token"]
                active = usr["active"]
            except KeyError or TypeError:
                self.send("Login: 0", False)
                return
            if (not loggedin) | (not active) | (not local.token) | (local.user["faction"] != "f"):
                self.send("Login: 0", False)
                return
            self.send("Login: 1", False)
            self.loggedon = True
            return

    def closed(self, code, reason=""):
        log("Closed!")
        wslist.remove(self)

And my JavaScript page (note, not the whole):

function init() {
            showBlocking("Connecting...", "progress-bar-success");
            var wsprotocol = (location.protocol == "https:") ? "wss://" : "ws://";
            var loc = location.pathname;
            loc = loc.replace(/live\u002flive$/i, "");
            var wsurl = wsprotocol + location.host + loc + "/live/ws_zones";
            console.log(wsurl);
            var ws = new WebSocket(wsurl);

            var key = getCookie("key");
            var id = getCookie("id");

            var closed = true;

            ws.onopen = function(evt) {
                console.log("onopen");
                $('#pbheader').text("Logging in...");
                ws.send("Login: " + id + ":" + key);
                closed = false;
            }

            ws.onmessage = function(evt) {
                console.log("OnMessage");
                var channel = evt.data.substring(0, 7);
                var data = evt.data.substr(6);
                if (channel == "Login: ") {
                    if (data == "0") {
                        ws.close();
                        closed = true;
                        alert("Invalid Login, please re-login.");
                        $('#pbheader').text("Invalid Login!");
                        history.back();
                    } else if (data == "1") {
                        hideBlocking();
                    }
                } else if (channel == "ZoneA: ") {
                    // add new thing...
                    // %gridref% %zoneid% %zonename% %faction% %legion% %faceless% %swarm%
                    var datadict = JSON.parse(data);
                    var replitem = itemtemplate.replace("%count%", count).replace("%gridref%", datadict.gridref).replace("%zoneid%", datadict.zoneid).replace("%zonename%", datadict.zonename).replace("%faction%", datadict.faction).replace("%legion%", datadict.legion).replace("%faceless%", datadict.faceless).replace("%swarm%", datadict.swarm);
                    $('#live').prepend(replitem);
                    var curritem = $('#item' + count);
                    setTimeout(function () { fadeoutremove(curritem); }, 60*1000);
                    count = count + 1;
                }
            }

            ws.onclose = function(evt) {
                console.log("Closed");
                closed = true;
            }

            ws.onerror = function(evt) {
                console.log("error");
                closed = true;
            }
        }

        window.addEventListener("load", init, false);

Mounting Service:

log("Starting WebServer (cherrypy)")
cherrypy.server.unsubscribe()
if config.DO_SSL is True:
    server1 = cherrypy._cpserver.Server()
    server1.socket_port = config.LISTEN_PORT_SSL
    server1._socket_host = config.LISTEN
    server1.thread_pool = 30
    server1.ssl_certificate = config.SSL_CERTIFICATE
    server1.ssl_private_key = config.SSL_PRIVATE_KEY
    server1.ssl_certificate_chain = config.SSL_CHAIN
    server1.ssl_module = config.SSL_HANDLER
    server1.subscribe()
server2 = cherrypy._cpserver.Server()
server2.socket_port = config.LISTEN_PORT
server2._socket_host = config.LISTEN
server2.thread_pool = 30
server2.subscribe()

WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tools.websocket = WebSocketTool()

cherrypy.tree.mount(APIService.APIService(), "/api", config={"/": {'error_page.404': APIService.ep}})
cherrypy.tree.mount(JSONService.JSONService(), "/json", config={"/": {'error_page.404': JSONService.ep}})
cherrypy.tree.mount(USRAPIService.USRAPIService(), "/usrapi", config={"/": {'error_page.404': USRAPIService.ep}})
cherrypy.tree.mount(USRAPIAdminService.USRAPIAdminService(), "/usrapi/admin", config={
    "/": {'error_page.404': USRAPIService.ep}})
cherrypy.tree.mount(RootService.RootService(), "/", config={"/": {'error_page.404': RootService.ep}})
cherrypy.tree.mount(AdminService.AdminService(), "/admin", config={"/": {'error_page.404': AdminService.ep}})
cherrypy.tree.mount(HelperPanel.HelperPanel(), "/helper", config={"/": {'error_page.404': HelperPanel.ep}})
cherrypy.tree.mount(LiveService.LiveService(), "/live", config={"/": {'error_page.404': LiveService.ep},
                                                                "/ws_zones": {'tools.websocket.on': True,
                                                                              'tools.websocket.handler_cls':
                                                                                  LiveService.LoginLiveWebSocketHandler
                                                                              }})
cherrypy.tree.mount(None, "/static", config={"/": {'error_page.404': AdminService.ep,
                                                   'tools.staticdir.on': True,
                                                   'tools.staticdir.dir':
                                                       os.path.join(__current_dir, "web/static")}})
cherrypy.engine.start()
log("Started WebServer (cherrypy)")

LiveService:

class LiveService(object):

    @cherrypy.expose
    @require(level=0)
    def index(self, user, usrname, usrhelper, usradmin):
        return render("index", usrname, usrhelper, usradmin)

    @cherrypy.expose
    @require(level=4)  # Require login, Groupme, active and faceless
    def live(self, user, usrname, usrhelper, usradmin):
        return render("websocket/zonesdata", usrname, usrhelper, usradmin)

    @cherrypy.expose
    def ws_zones(self):
        log("Handler created: %s" % repr(cherrypy.request.ws_handler))
        cherrypy.request.ws_handler.send(b"Login 0", False)

So, the mounting and starting works, the whole run in production for months now, but the new LiveService with ws is not working. In log, im getting [21/Jul/2015:16:55:28] ENGINE Starting WebSocket processing and Opened Messages, but I never receive or able to send Messages. When I change LiveService.LoginLiveServiceWebSocketHandler to EchoWebSocket he gets Messages and sends them, but on ws_zones handler

cherrypy.request.ws_handler.send(b"Login 0", False)

is not working. wether with the b or not.


Solution

  • Was a bit stupid...

    @saaj was right, but the real Problem was that I tried to call function log (which requires str) with m, m.data etc. Doing this with either repr() or removing it, it worked!

    Thanks!