3

Problem

So I need to make a python application that can sit on a machine, open up a websocket pipe to a server running flask-socketio, then pipe data across to the server. The data will be json data, for now I am testing with a string.

I am having an issue using the 'websockets' library in python to connect to the 'flask-socketio' backend that I am making.

Code

Server

from flask import Flask, render_template, request, url_for, copy_current_request_context from flask_socketio import SocketIO, emit import logging logging.basicConfig() app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' app.config['DEBUG'] = True socketio = SocketIO(app) @socketio.on('connect', namespace='/') def connect(): print('Client connected') @socketio.on('disconnect', namespace='/') def disconnect(): print('Client disconnected') if __name__ == '__main__': socketio.run(app, debug=True) 

Client 1 - websockets library

import asyncio import websockets async def hello(): async with websockets.connect( 'ws://127.0.0.1:5000') as websocket: name = 'joe' # input("What's your name? ") await websocket.send('message', name) print(f"> {name}") greeting = await websocket.recv() print(f"< {greeting}") asyncio.get_event_loop().run_until_complete(hello()) print("end") 

Use output

When I use client 1 I get this as output on the client process: Traceback (most recent call last): File "C:/project_files/aWebUAS/micro-services/New-Capabilities-Investigation/web_socket_client.py", line 15, in <module> asyncio.get_event_loop().run_until_complete(hello()) File "C:\Program Files\Anaconda3\lib\asyncio\base_events.py", line 466, in run_until_complete return future.result() File "C:/project_files/aWebUAS/micro-services/New-Capabilities-Investigation/web_socket_client.py", line 6, in hello 'ws://127.0.0.1:5000') as websocket: File "C:\Program Files\Anaconda3\lib\site-packages\websockets\py35\client.py", line 2, in __aenter__ return await self File "C:\Program Files\Anaconda3\lib\site-packages\websockets\py35\client.py", line 20, in __await_impl__ extra_headers=protocol.extra_headers, File "C:\Program Files\Anaconda3\lib\site-packages\websockets\client.py", line 286, in handshake raise InvalidStatusCode(status_code) websockets.exceptions.InvalidStatusCode: Status code not 101: 404

and on the flask process I see:
127.0.0.1 - - [2019-04-05 09:17:13] "GET / HTTP/1.1" 404 342 0.000999

Client 2 - websocket-client library

import websocket ws = websocket.WebSocket() ws.connect("ws://127.0.0.1:5000") ws.send("Hello, World") 

Use output

On the client 2 process I get this as output: Traceback (most recent call last): File "C:/project_files/aWebUAS/micro-services/New-Capabilities-Investigation/web_socket_client_2.py", line 3, in <module> ws.connect("ws://127.0.0.1:5000") File "C:\Program Files\Anaconda3\lib\site-packages\websocket\_core.py", line 226, in connect self.handshake_response = handshake(self.sock, *addrs, **options) File "C:\Program Files\Anaconda3\lib\site-packages\websocket\_handshake.py", line 79, in handshake status, resp = _get_resp_headers(sock) File "C:\Program Files\Anaconda3\lib\site-packages\websocket\_handshake.py", line 160, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 404 NOT FOUND

and the flask process shows this:
127.0.0.1 - - [2019-04-05 09:11:57] "GET / HTTP/1.1" 404 342 0.001000

Conclusion

Some reading around tells me I am not hitting my socketio handler within flask properly, but I am unsure how to target that.

Any help is much appreciated. My goal is to have a python script talking to a flask socketio server. I am not married to any part of this but would prefer to stick to flask for the server.

TIA - Ian

1 Answer 1

4

You may have figured this out by now, but the issue is likely the fact that flask-socketio is a Socket.IO implementation, not a websocket implementation. Socket.IO uses websockets as one of its communication protocols, but you will need a Socket.IO client to connect to the flask-socketio server.

See socketio's docs, specifically:

Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the ack id when a message acknowledgement is needed. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a WebSocket server either.

Take a look at this python Socket.IO client. https://github.com/miguelgrinberg/python-socketio

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.