websocket-client / websocket-client

WebSocket client for Python

Home Page:https://github.com/websocket-client/websocket-client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AttributeError: 'NoneType' object has no attribute 'connected'

josepalos opened this issue · comments

My on_open callback sends some data to the server when the connection is established. Usually, it works, but some times i receive the following error.

The following exception is captured in the on_error callback.

Traceback (most recent call last):
  File "[...]/python3.5/site-packages/websocket/_app.py", line 278, in run_forever
    dispatcher.read(self.sock.sock, read)
  File "[...]/python3.5/site-packages/websocket/_app.py", line 48, in read
    while self.app.sock.connected:
AttributeError: 'NoneType' object has no attribute 'connected'

I'm afraid I cannot provide more useful data to reproduce the problem as it appears to be raised randomly.

I'm getting this too. Did you find any fix?

As far as I know, I get this error when the server (done with django channels) has an exception while processing a message sent.
I suspect it is because the connection is broken before an exception is caught.

My websocket-client is using "run_forever". If I close the websocket in the other thread right after receiving a message from server, I would randomly saw this issue. From the src code of close(), it sets sock to None, which caused the while loop in the read() 'NoneType'

Will anyone take a look at this?

commented

I get the error message as well:
'NoneType' object has no attribute 'connected'

  • Linux ES 4.19.4-arch1-1-ARCH #1 SMP PREEMPT Fri Nov 23 09:06:58 UTC 2018 x86_64 GNU/Linux
  • Python 2.7.15
  • websocket-client version 0.54.0

I have the same problem when I close socket.

    def on_message(ws: WebSocketApp, message):
        print(message)
        ws.close()

    def on_error(ws, error):
        print(error)

It triggers on_error: 'NoneType' object has no attribute 'connected'

commented

for me this problem happens rarely. not sure what reason, but for quick "fix" im subclassed WebSocket and added checking of existed attributes and object type - if problem happens now, i'm just switch greenlet and try to do this again on next switch. usually this trick need to be repeated 1-4 times before i can correctly do my actions. so looks like this bug near race-conditions or smtng etc.

im my case

I have the same problem when I close socket.

    def on_message(ws: WebSocketApp, message):
        print(message)
        ws.close()

    def on_error(ws, error):
        print(error)

It triggers on_error: 'NoneType' object has no attribute 'connected'

I was tryings things out and called close() method on socket by mistake. After removing it worked for me.

@robie2011 : As per README, close() method is called on websocket object from callback. How did you work-around to close?

@robie2011 : As per README, close() method is called on websocket object from callback. How did you work-around to close?

In my case, I wanted to keep the websocket connection open - forever. Therefore I don't need a call for close function.
See https://gist.github.com/robie2011/1cd3fc30fa2afc0c4b698cddf378e83d

In my case, After each send I was receiving message and OPCODE of closing connection from server side. So, websocket-client used to teardown connection and making sock object None. And I used call close() explicitly which was throwing an error.

我也遇到同样的问题,在on_message里面调用ws.close()时就提示NoneType错误,但是在on_open里面调用它却不会报错,于是我在on_open的时候给ws添了一个标记,置为false, 并循环等待标记值变化,在on_message里面探测到最后一帧数据时,将这个标记置为true, 再执行on_open后面的ws.close()就正常结束了。

I experience the same issue, the on_error() method is called when I close the websocket connection with ws.close().

I need to be able to reconnect my client websocket with new credentials for the header once the server sent the client a message with new credentials to use. So how do I reconnect without having this error?

Update: I tested a bit more and realized that these errors occur when I terminate my program on the command line with Ctrl + C. For as many times I closed and reconnected the websocket, I get an error message from the on_error() method.

Bildschirmfoto 2019-10-27 um 11 30 53

I have the same problem when I close socket.

    def on_message(ws: WebSocketApp, message):
        print(message)
        ws.close()

    def on_error(ws, error):
        print(error)

It triggers on_error: 'NoneType' object has no attribute 'connected'

I meet the same issue.

commented

Update:

I've found the culprit here, the reason is that in the default dispatcher, it uses select.select on the underlying socket, but that is not thread safe. So if the ws_app.close is called in some other thread, that thread might well get data from select.select((socket, )), the same socket as the dispatcher.read(). This will cause the select in read method blocks until the ping_timeout reached and then without checking keep_running, it checks the sock.connected, whereas sock has been set to None.

The default dispatcher checks self.app.sock.connected
The reason you could possibly see this exception is that:
for example, the client calls the close() first, then we send CLOSEOP, and server returns CLOSEOP and then FIN+ACK the conn, depending on the server implementation though, but anyhow, if the FIN+ACK arrives before the CLOSEOP we will never see the CLOSEOP from the underlying socket. Whereas the select call in default dispatcher still has a timeout of 10s. As long as in this 10s period, we have set wsapp.sock to None, then after the select times out after 10s, the ws.sock is None, the read loop in dispatcher will throw the exception

 def create_dispatcher(self, ping_timeout):
        timeout = ping_timeout or 10  # set it to 10 if None is given
    def read(self, sock, read_callback, check_callback):
        while self.app.sock.connected:  # exception here
            r, w, e = select.select(
                    (self.app.sock.sock, ), (), (), self.ping_timeout)  # during the ping_timeout period, the self.app.sock could already be None
commented

a proposed solution to this , is to use self.keep_running instead of self.app.sock.connected, perhaps we need more checks around the socket.

I've tried to remove ws.close() in on_message, there was a gap time with no response which continues serveral seconds, maybe 10s or less.
So, I agree with @imcom.

I am facing same issue and made two perfromance tests with different results.

Test 1

  1. Openend connections to around 50 different websockets by threads
  2. In on_open() just closed them again after 1 second. time.sleep(1) and ws.close
  3. The on_close() gave an exception aswell: No attribute 'sock'.
  4. in the on_close() I have a reconnect with run_forever()
    Result Test 1: Sockets are connecting again and again. not a big thing

Test 2

  1. Openend connections to around 50 different websockets by threads
  2. In on_open() just send ws.ping("ping") to socket.
  3. In on_message() just closed them again after 1 second. time.sleep(1) and ws.close. gave an exception aswell: No attribute 'connected'.
  4. in the on_close() I have a reconnect with run_forever()
    Result Test 2: Sockets are connecting again and again. but brings a problem.

where in Test 1, the private bytes memory stays low, it raises from 40MB until 2GB into around 2minutes in Test 2.

Any idea why this happens when close in on_message() but not in on_open()

Looks like this got fixed by PR #586 which was already merged