As stated in the documentation for whatwg.org Websocket (this is a copy from a standard project):
The constructor of WebSocket (url, protocol) takes one or two arguments. The first argument, url, specifies the URL to connect to. Second, the protocols, if any, are either a string or an array of strings. If it is a string, it is equivalent to an array consisting only of that string; if omitted, it is equivalent to an empty array. Each row in the array is a subprotocol name. A connection will be established only if the server reports that it has selected one of these sub-protocols . Subprotocol names must be strings that meet the requirements for elements that contain the value of the Sec-WebSocket-Protocol fields, as defined in the WebSocket protocol specification.
Your server responds to a websocket connection request with an empty Sec-WebSocket-Protocol header, as it does not support the Chat-1 sub Chat-1 protocol.
Since you write both on the server side and on the client side (and if you do not write the API that you intend to share), it should not be super important to set a specific sub-protocol name.
This can be fixed by removing the subprotocol name from the javascript connection:
var socket = new WebSocket(serviceUrl);
Or changing your server to support the requested protocol.
I could give an example of Ruby, but I cannot give an example of Python, since I do not have enough information.
EDIT (Ruby example)
Since I was asked in the comments, here is an example of Ruby.
In this example, the iodine HTTP / WebSockets server is required because it supports the rack.upgrade specification of the rack.upgrade (the concept is described in detail here ) and adds the pub / sub API.
Server code can be executed either through the terminal or as a Rack application in the config.ru file (run iodine from the command line to start the server):
# frozen_string_literal: true class ChatClient def on_open client @nickname = client.env['PATH_INFO'].to_s.split('/')[1] || "Guest" client.subscribe :chat client.publish :chat , "#{@nickname} joined the chat." if client.env['my_websocket.protocol'] client.write "You're using the #{client.env['my_websocket.protocol']} protocol" else client.write "You're not using a protocol, but we let it slide" end end def on_close client client.publish :chat , "#{@nickname} left the chat." end def on_message client, message client.publish :chat , "#{@nickname}: #{message}" end end module APP
To test the code, the following JavaScript should work:
ws = new WebSocket("ws://localhost:3000/Mitchel", "chat-1.0"); ws.onmessage = function(e) { console.log(e.data); }; ws.onclose = function(e) { console.log("Closed"); }; ws.onopen = function(e) { e.target.send("Yo!"); };