🎓 A1Learner
🔍
0 of 42 lessons completed

Chat: Holding the Connection Open

A connection is a link between a phone and a server that stays ready for messages. This lesson designs the high-level connection and compares three ways to keep it ready.

Three ways to deliver the same 3 messages

Three messages arrive at scripted steps in a short run. The printout counts the requests each style makes to deliver those same messages.

arrival_steps = [3, 6, 9]
steps = list(range(1, 11))
polling_requests = 0
polling_delivered = 0
for step in steps:
    polling_requests += 1
    if step in arrival_steps:
        polling_delivered += 1
long_polling_requests = 0
long_polling_delivered = 0
for step in arrival_steps:
    long_polling_requests += 1
    long_polling_delivered += 1
websocket_connections = 1
websocket_delivered = len(arrival_steps)
print("polling:", polling_requests, "requests,", polling_delivered, "messages")
print("long polling:", long_polling_requests, "requests,", long_polling_delivered, "messages")
print("WebSocket:", websocket_connections, "connection,", websocket_delivered, "messages")

Sizing the connection fleet

Each connection server holds a fixed number of open connections. Dividing the online users by that figure gives the fleet size.

online_users = 10000000
connections_per_server = 100000
servers = online_users // connections_per_server
print("users online at once:", online_users)
print("connections per server:", connections_per_server)
print("connection servers needed:", servers)

One connection carrying both directions

A held-open connection carries a message up from the phone and a reply down from the server. The printout counts the connections opened and the messages carried.

sent = ["hi", "how are you"]
received = ["hello", "fine, thanks"]
connections_opened = 1
carried = 0
for text in sent:
    carried += 1
    print("phone to server:", text)
for text in received:
    carried += 1
    print("server to phone:", text)
print("connections opened:", connections_opened)
print("messages carried:", carried)

Example

users = ["Ana", "Bo", "Cy", "Dee", "Eli", "Fay", "Gil", "Hal", "Ivy", "Jay"]
servers = ["server A", "server B", "server C"]
capacity = 4
placed = {name: [] for name in servers}
for i, user in enumerate(users):
    placed[servers[i // capacity]].append(user)
for name in servers:
    print(name, "holds", len(placed[name]), "connections")
print("total connections:", sum(len(placed[name]) for name in servers))
print("push to Jay:", "one new message")

Key points

  • Polling: the phone asks again and again whether anything new has arrived.
  • Long polling: the server holds one request open until a message arrives or time runs out, then answers.
  • WebSocket: a connection held open so the server can push a message the moment it arrives.
  • Push: the server starts the delivery instead of waiting for the phone to ask.
  • Connection server: a server whose whole job is holding open connections.
  • Fleet size: 10,000,000 online users at 100,000 connections per server need 100 connection servers.

In this example, each connection server fills to its capacity before the next one takes users. One held-open connection per user then lets the server push a new message straight to the right phone.

Note

a WebSocket connection carries messages in both directions, which suits chat well.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Which style opens one connection and lets the server push a message the moment it arrives?