2

I'm creating a Python socketserver using the module socketserver:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def setup(self):
        pass
    def handle(self):
        pass
with socketserver.TCPServer(("localhost", 4000), MyTCPHandler) as server:
    server.serve_forever()

I've used the Python module websockets and I could access the websocket in Javascript using the WebSocket API. Without fully understanding what the Python module socketserver really does, I attempted to connect to the TCP socketserver using a websocket:

var socket = new WebSocket('ws://localhost:4000'); // ERROR: Firefox can’t establish a connection to the server at ws://localhost:4000/.

Everytime, Firefox threw the error Firefox can’t establish a connection to the server at ws://localhost:4000/. Then, I tried connecting to the server using the Python http module:

import http.client
httpConnection = http.client.HTTPSConnection("localhost:4000", timeout=10)
print(httpConnection) # HTTP Connection Object

Sadly, this worked. Now, I understand that Python's built-in socketserver module creates can only be accessed through HTTP. Now, I want to know if it is possible to connect to a Python TCP socketserver with Javascript in the browser. If not, I'll just use websockets or figure out how to create my own websocket.

2 Answers 2

1

With socketserver, you would have to implement the websocket protocol in your code. There are several tutorials on the web, e.g. here.

Sign up to request clarification or add additional context in comments.

2 Comments

So, essentially, a websocket is just an HTTP connection with extra headers? And the server just needs to do some extra handling?
It's not a HTTP connection but similar. Unlike HTTP, WebSocket provides full-duplex communication. WebSocket enables streams of messages on top of TCP on port 80 or 443. The WebSocket handshake uses the HTTP Upgrade header to change from the HTTP protocol to the WebSocket protocol. So yes, the server needs to do extra handling for websocket. You can read more about the websocket protocol e.g. on Wikipedia.
0

While the link to the blog from @scenox was very helpful, it was outdated. I did a bit more searching and fixed it to better reflect today's standards for a websocket:

def setup(self):
    print(type(self))
    data = str(self.request.recv(1024))
    if "Upgrade: websocket" in data: # Connection: Upgrade might be Connection: keep-alive, Upgrade
        key = base64.b64encode(hashlib.sha1((data.split("Sec-WebSocket-Key: ")[1].split("\\r\\n")[0] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode('ascii')).digest()).decode('ascii') # Encode as ascii and then decode it
        self.request.sendall(f"HTTP/1.1 101 Switching Protocols\r\nSec-WebSocket-Accept: {key}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n".encode()) # Encode it so that it gets sent as a bytes-like object
        while True:
            # I haven't figured out how to decode frames yet.
    else:
        self.request.sendall("HTTP/1.1 400 Bad Request\r\n" + \
                             "Content-Type: text/plain\r\n" + \
                             "Connection: close\r\n" + \
                             "\r\n" + \
                             "Incorrect request")

I still have yet to decode frames, but I at least established the connection.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.