Simple Python Socketio Server (Help!)

I am trying to deploy a simple Python socketio server.
I’ve tested it locally and it works. But when I put it on fly.io my webpage client can never reach it and it crashes.

Here is my `server.py`
import socketio
import eventlet

print("Hello Fly.io!")

IP = "fly-global-services"
# IP = "127.0.0.1"
PORT = 5000

sio = socketio.Server(async_mode='eventlet',cors_allowed_origins='*')
app = socketio.WSGIApp(sio)

@sio.event
def connect(sid, environ):
	print('new connection: ', sid)

@sio.event
def Client(sid, *data):
	print("received message from client:",sid)
	print("the contents of the message were:",*data)

@sio.event
def disconnect(sid):
	print('disconnected from: ', sid)

eventlet.wsgi.server(eventlet.listen((IP, PORT)), app)
print("this should not print")
Here is my `requirements.txt`
python-socketio
eventlet
Here is my `Dockerfile`
ARG PYTHON_VERSION=3.7

FROM python:${PYTHON_VERSION}

RUN apt-get update && apt-get install -y \
    python3-pip \
    python3-venv \
    python3-dev \
    python3-setuptools \
    python3-wheel

RUN mkdir -p /app
WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .


# replace APP_NAME with module name
CMD ["python", "server.py"]
Here is my `fly.toml`
# fly.toml file generated for firstsocketio on 2022-04-17T16:44:44+01:00

app = "firstsocketio"

kill_signal = "SIGINT"
kill_timeout = 5
processes = []

[env]
  PORT = "5000"

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 5000
  processes = ["app"]
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

[[statics]]
  guest_path = "/app/public"
  url_prefix = "/static/"
Here is my client page, hosted locally or elsewhere
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<script src="https://cdn.socket.io/4.4.1/socket.io.min.js" integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H" crossorigin="anonymous"></script>
	<title>simple socketio client</title>
</head>
<body>
	<form onsubmit="update_vars(); connect2server(); return false">
	  <label for="ip">Server ip:</label><br>
	  <input type="text" id="ip" name="ip" value="firstsocketio.fly.dev"><br><br>
	  <!-- <label for="port">Server port:</label><br>
	  <input type="number" id="port" name="port" value="80"><br><br> -->
	  <input type="submit" value="Connect">
	</form><br><br>

	<form onsubmit="sendmessage(); return false">
	  <label for="ip">Message:</label><br>
	  <input type="text" id="message" name="message" value="hello world!"><br><br>
	  <input type="submit" value="Send">
	</form><br><br>

	<script type="text/javascript">
		var ip = document.getElementById('ip').value;
		// var port = document.getElementById('port').value;

		function update_vars() {
			ip = document.getElementById('ip').value;
			// port = document.getElementById('port').value;
		}

		function connect2server() {
			// var address="http://"+ip+":"+port;
			var address="https://"+ip;
			console.log("address:",address);
			socket = io(address);
			socket.on("connect", () => {
			  console.log("connected to server",socket.id);
			  alert("connected to server",socket.id);
			});
			socket.on("disconnect", () => {
			  console.log("server disconnected",socket.id);
			  alert("server disconnected",socket.id);
			});
			socket.on("response", (data) => {
			  console.log(data,socket.id);
			});
		}

		function sendmessage() {
			var message = document.getElementById('message').value;
			socket.emit('Client', message);
		}

	</script>
</body>
</html>

Thank you very much for your help!

Hi there!

What’s crashing is the server or the client?

If it’s the server, can you share you latest logs and if it’s your client can you share console errors and/or network responses?

Can I assume your client is trying to connect to https://youflyapp.fly.dev using 443 (default) port?

@lubien

The server:

2022-04-17T16:03:47Z   [info]Unpacking image
2022-04-17T16:03:49Z   [info]Configuring firecracker
2022-04-17T16:03:49Z   [info]Starting virtual machine
2022-04-17T16:03:49Z   [info]Starting init (commit: 252b7bd)...
2022-04-17T16:03:49Z   [info]Preparing to run: `python server.py` as root
2022-04-17T16:03:49Z   [info]2022/04/17 16:03:49 listening on [fdaa:0:5a7f:a7b:2808:a612:7f97:2]:22 (DNS: [fdaa::3]:53)
2022-04-17T16:07:04Z   [error]Error 1: Undocumented
--> v0 failed - Failed due to unhealthy allocations - no stable job version to auto revert to and deploying as v1 

The client:

(nothing)

Yes, in this case to: https://firstsocketio.fly.dev
with the line 37 of the html file: socket = io(address);
where address is https://firstsocketio.fly.dev generated from the form inputs :slight_smile:

It appears that your server is not listening in the proper place. Can you change your “IP” constant to “127.0.0.1” or “0.0.0.0” and try to deploy?

Usually “Failed due to unhealthy allocations” means you fly.toml checks (in this case TCP checks) were not being successful therefore they assumed the deployment did not go right.

Oh! I thought we were supposed to always put it as fly-global-services
Let me try…

@lubien
Nope still crashing, now at least it printed some of the things it should print to the console though:

2022-04-17T16:42:43.456 runner[c335da21] lhr [info] Starting virtual machine
2022-04-17T16:42:43.710 app[c335da21] lhr [info] Starting init (commit: 252b7bd)...
2022-04-17T16:42:43.732 app[c335da21] lhr [info] Preparing to run: `python server.py` as root
2022-04-17T16:42:43.755 app[c335da21] lhr [info] 2022/04/17 16:42:43 listening on [fdaa:0:5a7f:a7b:a98:c335:da21:2]:22 (DNS: [fdaa::3]:53)
2022-04-17T16:44:39.105 proxy[a6127f97] lhr [error] Error 1: Undocumented
2022-04-17T16:45:01.552 proxy[a6127f97] lhr [error] Error 1: Undocumented
2022-04-17T16:45:23.257 proxy[c335da21] lhr [error] Error 1: Undocumented
2022-04-17T16:45:48.252 proxy[c335da21] lhr [error] Error 1: Undocumented
2022-04-17T16:46:13.275 proxy[a6127f97] lhr [error] Error 1: Undocumented
2022-04-17T16:47:51.221 runner[c335da21] lhr [info] Shutting down virtual machine
2022-04-17T16:47:51.412 app[c335da21] lhr [info] Sending signal SIGINT to main child process w/ PID 515
2022-04-17T16:47:51.414 app[c335da21] lhr [info] (515) wsgi starting up on http://127.0.0.1:5000
2022-04-17T16:47:51.414 app[c335da21] lhr [info] wsgi exiting
2022-04-17T16:47:51.414 app[c335da21] lhr [info] (515) wsgi exited, is_accepting=True
2022-04-17T16:47:51.414 app[c335da21] lhr [info] Hello Fly.io!
2022-04-17T16:47:51.414 app[c335da21] lhr [info] this should not print
2022-04-17T16:47:52.417 app[c335da21] lhr [info] Main child exited normally with code: 0
2022-04-17T16:47:52.417 app[c335da21] lhr [info] Starting clean up.
2022-04-17T16:47:05.071 proxy[a6127f97] lhr [error] Error 1: Undocumented

It seems your app does start but your library suddenly exits

I don’t understand why, it is a very simple example, and it runs just fine locally.
Can you try deploying it?

Do you have a repo somewhere I can clone?

@lubien
here

@lubien
BTW, you can use the client page directly from github pages too:
here

@lubien
Any luck?

Hi. Sorry for the late reply. I could not clone to test it yet myself but I was wondering if you had any progress on this?

Hi @lubien

I am pretty much still stuck, with no idea why it is failing.
I want to believe it is not because of cors, since I’ve long dealt with that in the python code (documentation reference here). I just don’t understand why it works when I test elsewhere, for example hosting the server myself and still connecting with the page online hosted elsewhere. But it just won’t work on fly.io. I’d appreciate if you could help figure this out.

This has to listen on 0.0.0.0: firstsocketio/server.py at main · omarcostahamido/firstsocketio · GitHub

Right now, it’s set to only listen on 172.0.0.1, we connect from a non-local (but still private) IP so we can’t currently connect to your app. This causes health checks to fail.

Once you deploy with 0.0.0.0, you should check two things:

  1. fly status --all to see if there are failing VMs
  2. fly vm status <id> to look at exit codes or health check failures

This is not related to cors, it’s just our ability to talk to your application process. fly-global-services is only for UDP apps, not relevant to TCP.

2 Likes

@kurt
OMG!..

I lost so many hours at this… Thank so much for clarifying all these.
(Such a silly error ooof!)

Thank you!