0
votes

I were just trying to use WebSockets. i wrote server code in python. The server is running fine but when tried to connect to the socket using browser, I'm getting the error

"WebSocket connection to 'ws://localhost:9876/' failed: Received unexpected continuation frame"

When referring on internet, I understood it is something related to framing of data that sent from the server. I've tried to follow these (rfc6455) standards when sending a data, even I can't achieve a websocket connection. Almost similar question is asked here, but it is an old post also the solution is not clear.

This is my pretty simple server code..

import socket

def handle(s):
    print repr(s.recv(4096))

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind(('',9876))
s.listen(2)

handshakes='\
HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Origin: null\r\n\
Sec-WebSocket-Location: ws://localhost:9876/\r\n\
'
def handshake(hs):
    hslist = hs.split('\r\n')
    body = hs.split('\r\n\r\n')[1]
    key = ''
    cc = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

    for h in hslist:
        if h.startswith('Sec-WebSocket-Key:'):
            key = h[19:]
        else:
            continue

    import hashlib
    import base64
    s = hashlib.sha1()
    s.update(key+cc)()
    h = s.digest()
    return base64.b64encode(h)

def sender(data, conn):
    first_byte = chr(0x00)
    payload = data.encode('utf-8')
    pl = first_byte + payload + chr(0xFF)
    conn.send(pl)

while True:
    c,a = s.accept()
    msg = c.recv(4096)
    if(msg):

        print msg
        print 'sending handshake ...'
        handshakes += 'Sec-WebSocket-Accept: '+str(handshake(msg))+'\r\n\r\n'
        print handshakes
        c.send(handshakes)
        sender("Hello", c)
        break;

And the html, index.html

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Web Socket Example</title>
    <meta charset="UTF-8">
    <script>
      window.onload = function() {
        var s = new WebSocket("ws://localhost:9876/");
        s.onopen = function(e) { alert("opened"); }
        s.onclose = function(e) { alert("closed"); }
        s.onmessage = function(e) { alert("got: " + e.data); }
      };
    </script>
  </head>
    <body>
      <div id="holder" style="width:600px; height:300px"></div>
    </body>
</html>

I'm running this code like this..

./server.py & python -m SimpleHTTPServer 8888

after running the server, when I hit localhost:8888 using browser, it alerts "opened" (means handshaking is done) at the same time alerts "closed" (connection closed) with the above error on console.

Not very clear how to debug this issue.

I'm using browser Chrome (version: 41), Python 2.7, Websocket 13.

1
It sounds likely that you have a webSocket framing error. I'd suggest you look at a network sniffer and compare how a browser interacts with your webSocket server and how the same browser interacts with a test and known good webSocket server like perhaps websocket.org/echo.html. The framing difference between the two will probably be clear. - jfriend00
If you're curious here's a nice diagram of what the webSocket frame is supposed to look like once the http handshake it done: developer.mozilla.org/en-US/docs/WebSockets/… - jfriend00
thanks jfriend00 for your links.. it really helps me to go forward - Sony George

1 Answers

0
votes

It works when I changed the sender function like this..

...

def sender(data, conn):
    length = len(data)

    if length <= 125:
        ret = bytearray([129, length])

        for byte in text.encode("utf-8"):
            ret.append(byte)

        conn.send(ret)

...