Sanic websockets log `event` periodically, but `ev

2019-08-18 01:56发布

问题:

I asked this question earlier about websockets in sanic. This is a follow up.

The following establishes a websocket connection and console.log()s the 'data' message exactly one time:

from sanic import Sanic, response
from sanic.websocket import WebSocketProtocol
import asyncio
import time

app = Sanic()

@app.websocket('/feed')
async def feed(request, ws):
    while True:
        now = time.time()
        data = 'messsage'
        print(data)
        await ws.send(data)
        await asyncio.sleep(1)

@app.route('/')
async def handle_request(request):
    return response.html("""
    <html><head>
    <script>
    const ws = new WebSocket("ws://" + location.host + '/feed');
    ws.onmessage = event => {
      console.log(event.data);
    }
    </script>
    </head>
    <body><h1>Main</h1></body>
    </html>
    """)

app.run(host="0.0.0.0", port=8000)

On the server side, "messsage" is printed periodically. But on the client side, it is console.logged only one time.

server:

client:

It is not clear to me why it prints only once, and not every second like the server side.

However, here are two conditions that /do/ make it print every second.

First, console.log(event), then console.log(event.data) logs periodically, correctly.

@app.route('/')
async def handle_request(request):
    return response.html("""
    <html><head>
    <script>
    const ws = new WebSocket("ws://" + location.host + '/feed');
    ws.onmessage = event => {
      console.log(event);      // THIS IS THE ONLY CHANGE
      console.log(event.data);  
    }
    </script>
    </head>
    <body><h1>Main</h1></body>
    </html>
    """)

That prints this on the client side:

Second, I can keep the javascript as the original,

ws.onmessage = event => {
  console.log(event.data);
}

but use the following message, which changes every time:

@app.websocket('/feed')
async def feed(request, ws):
    while True:
        now = time.time()
        data = f'messsage: {now}'  # THIS IS THE ONLY CHANGE
        print(data)
        await ws.send(data)
        await asyncio.sleep(1)

That prints this on the server side:

messsage: 1565664622.570395
messsage: 1565664623.572094
messsage: 1565664624.5735717
messsage: 1565664625.5754132
messsage: 1565664626.5771558
messsage: 1565664627.5785906

And this on the client side:

So, these two seemingly irrelevant things take my websocket which does not log to the client side, and makes it do so. Why is this happening?