Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket is not closed after client left #119

Open
vzarutskiy opened this issue Apr 14, 2023 · 1 comment
Open

Socket is not closed after client left #119

vzarutskiy opened this issue Apr 14, 2023 · 1 comment

Comments

@vzarutskiy
Copy link

vzarutskiy commented Apr 14, 2023

Python-dbg detected warning during websocket server working:

[INFO 2023.04.12 21:14:58 Thread-2:warnings.py:30][_showwarnmsg_impl]: ****:164: ResourceWarning: unclosed <socket.socket [closed] fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
if check_str in list(self.check_pattern_callbacks.keys()):
Object allocated at (most recent call last):
File "/usr/lib/python3.8/threading.py", lineno 890
self._bootstrap_inner()
File "/usr/lib/python3.8/threading.py", lineno 932
self.run()
File "/home/user/.local/lib/python3.8/site-packages/websocket_server/thread.py", lineno 27
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.8/socketserver.py", lineno 237
self._handle_request_noblock()
File "/usr/lib/python3.8/socketserver.py", lineno 311
request, client_address = self.get_request()
File "/usr/lib/python3.8/socketserver.py", lineno 502
return self.socket.accept()
File "/usr/lib/python3.8/socket.py", lineno 293
sock = socket(self.family, self.type, self.proto, fileno=fd)

Real socket closing happens in case where self._io_refs = 0 (socket.py):

    def close(self):
        # This function should not reference any globals. See issue #808164.
        self._closed = True
        if self._io_refs <= 0:
            self._real_close()

self._io_refs is used in makefile (socket.py):

def makefile(self, mode="r", buffering=None, *,
             encoding=None, errors=None, newline=None):
    ...
    self._io_refs += 1
    ...
    return text

makefile is used in "setup" from StreamRequestHandler (socketserver.py):

class StreamRequestHandler(BaseRequestHandler):
    ...
    def setup(self):
        ...
        self.rfile = self.connection.makefile('rb', self.rbufsize)
        if self.wbufsize == 0:
            self.wfile = _SocketWriter(self.connection)
        else:
            self.wfile = self.connection.makefile('wb', self.wbufsize)

    def finish(self):
        ...
        self.wfile.close()
        self.rfile.close()

Stream closing, which was opened by makefile happens in "finish" method of StreamRequestHandler, but this method does not execute in WebSocketHandler, only StreamRequestHandler.setup(self):

class WebSocketHandler(StreamRequestHandler):
    ...
    def setup(self):
        StreamRequestHandler.setup(self)
        self.keep_alive = True
        self.handshake_done = False
        self.valid_client = False
    ...
    def finish(self):
        self.server._client_left_(self)

Possible fix:

def finish(self):
    StreamRequestHandler.finish(self)
    self.server._client_left_(self)
@adamkennedyasurion
Copy link

I'm having the same issue here. Unfortunately, the "Possible fix" did not help me. I still haven't been able to figure it out.

def finish(self):
    StreamRequestHandler.finish(self)
    self.server._client_left_(self)

The only obvious pattern I have found is that it occurs when a client's browser idles or disconnects in the middle of the server transmitting a message to it. I just don't know how to disconnect/stop that one specific client that idled out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants