websocket-client / websocket-client

WebSocket client for Python
https://github.com/websocket-client/websocket-client
Apache License 2.0
3.57k stars 766 forks source link

Websocket app and automatic close frame #188

Closed fefe78 closed 9 years ago

fefe78 commented 9 years ago

Hi,

I'm trying to deal with an external websocket server (not mine), but what is happening is that after 45 seconds the socket send something to the server, and the server close the connection down (maybe it does not recognize the data sent). What the socket is automatically sending? No ping is set. I send a Keepalive to the server, but with or without, the behaviour is the same.

Here is an example:

--- request header ---
GET /xxx HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: xxx:8080
Origin: xxx:8080
Sec-WebSocket-Key: objJGIrMSwOy0DBW1Htzgg==
Sec-WebSocket-Version: 13
-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: lN4ER11bY4H1kAgI9uDukdbZQ6k=
-----------------------
11:46:50.648589 => sending data...
send: '\x81\x90\x10\xf1\xe2\xa6x\x94\x8e\xca\x7f\xd1\x84\xc5c\x94\x90\xd0u\x83\xe8\xa6'
send: '\x81\x9e}3\xce\xb2L\x13\xfe\x92M\x13\xfc\x82M\x04\xff\x82O\x06\xee\x82]T\xbb\xd7\x0eG\xf4\xd5\x08V\xbd\xc6w3'
11:46:51.015018 => Received data
11:46:51.016350 => Send data
send: '\x81\x9b\n]\xe89;m\xc8\t*m\xc8\x0e9d\xde\x0f2i\xda\x00*m\xc8ty\x11\x81UsW\xe8'
11:46:51.286685 => Received data
11:47:05.662669 => sending KeepAlive
send: '\x81\x8b]op\x00mO@ mOA mep'
11:47:05.667143 => KeepAlive sent
send: '\x88\x822\xe0\xee21\x08' => this is automatically sent
11:47:35.501901 => ### closed ###
liris commented 9 years ago

send: '\x88\x822\xe0\xee21\x08' => this is automatically sent

websocket client sent the "close" frame and the connection was lost. I didn't figure out why client sent such a frame.

Could you upload the source code? and which websocket server are you using?

fefe78 commented 9 years ago

Hi liris,

thanks for reply. Here is the minimized code:

import socket
import websocket
import threading
import time
import sys
import datetime
import json
import urllib2

def log(string):
    print str(datetime.datetime.now().time()) + " => " + string

def on_message(ws, message):
    buffer=message
    while len(buffer) > 12:
      datalength=int(buffer[0:4])
      if len(buffer) < datalength + 4:
    return #//wait for more data

      data = buffer[4:datalength + 4]

      if len(data) != datalength:
    break; #malformed message

      log(data)

      buffer = buffer[datalength + 4:]

def on_error(ws, error):
    print error

def on_close(ws):
    log( "### closed ###")

def sendKeepAlive():
  log("sending KeepAlive")
  ws.send("0 0 0 1 0\n\0")
  log("KeepAlive sent")

def login(ws):
    log("sending login...")
    ws.send("hello fcserver\n\0")
    ws.send("1 0 0 20071025 0 guest:guest\n\0")
    t = threading.Timer(15.0, sendKeepAlive)
    t.start()

if __name__ == "__main__":
    try:
      websocket.enableTrace(True)
      ws = websocket.WebSocketApp("ws://xchat9.myfreecams.com:8080/fcsl",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
      ws.on_open = login
      ws.run_forever(ping_interval=100)
    except KeyboardInterrupt:
        log("Ok ok, quitting")
        t.cancel()
        ws.close()
        sys.exit(1)

Essentially I connect to the websocket server defined with the websocket app.. send a hello packet and a login packet.. then a burst of data starting to come.. After 45 secs you should see the close frame.

thanks.

liris commented 9 years ago

Source code looks OK. Please give me information of stack trace when the on_close is called.

def on_close(ws):
    import traceback
    traceback.print_stack()
    log( "### closed ###")
fefe78 commented 9 years ago

Here it is... anyway I'm using python 2.7 on raspberrypi 3.12.28+ ... if the problem could be environment related.. Anyway you can run the code above by yourself.. it should work..

send: '\x88\x82\xd1aNB\xd2\x89'
  File "MFC_socket_test.py", line 57, in <module>
    ws.run_forever(ping_interval=100)
  File "/usr/local/lib/python2.7/dist-packages/websocket/_app.py", line 210, in run_forever
    *self._get_close_args(close_frame.data if close_frame else None))
  File "/usr/local/lib/python2.7/dist-packages/websocket/_app.py", line 231, in _callback
    callback(self, *args)
  File "MFC_socket_test.py", line 34, in on_close
    traceback.print_stack()
09:55:24.532420 => ### closed ###
liris commented 9 years ago

It seems websocket servet sent the "close" frame and the client reply it. Can you confirm the server sent it?

fefe78 commented 9 years ago

Sorry for delay.. It was my fault.. Not sending correctly the keppalive frame to server.. so I was kicked out. Sorry for that. Thanks for help.