I have the following code for a Sanic hello world based off combining different endpoints here:
- https://sanic.readthedocs.io/en/latest/sanic/response.html
- https://sanic.readthedocs.io/en/latest/sanic/websocket.html
Code is:
from sanic import Sanic
from sanic import response
from sanic.websocket import WebSocketProtocol
app = Sanic()
@app.route("/")
async def test(request):
return response.json({"hello": "world"})
@app.route('/html')
async def handle_request(request):
return response.html('<p>Hello world!</p>')
@app.websocket('/feed')
async def feed(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
@app.route('/html2')
async def handle_request(request):
return response.html("""<html><head><script>
var exampleSocket = new WebSocket("wss://0.0.0.0:8000/feed", "protocolOne");
exampleSocket.onmessage = function (event) {
console.log(event.data)};</script></head><body><h1>Hello socket!</h1><p>hello</p></body></html>""")
app.run(host="0.0.0.0", port=8000)
# app.run(host="0.0.0.0", port=8000, protocol=WebSocketProtocol) # ws
The routes "/" and "/html" work fine, but
http://0.0.0.0:8000/feed
produces:
Error: Invalid websocket request
and "/html2" renders the page fine, but doesn't log to console, showing in the debugger:
Firefox can’t establish a connection to the server at wss://0.0.0.0:8000/feed.
What should I change or add to make a viable websocket endpoint that plays nicely with the http ones, too?
Using 0.0.0.0 as your endpoint within your client html doesn't make any sense and you're not using SSL so you want to use ws:// rather than wss://. In other words,
from sanic import Sanic
from sanic import response
from sanic.websocket import WebSocketProtocol
app = Sanic()
@app.websocket('/feed')
async def feed(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
@app.route('/html2')
async def handle_request(request):
return response.html("""<html><head><script>
var exampleSocket = new WebSocket("ws://" + location.host + '/feed');
exampleSocket.onmessage = function (event) {
console.log(event.data)};</script></head><body><h1>Hello socket!</h1><p>hello</p></body></html>""")
app.run(host="0.0.0.0", port=8000)
来源:https://stackoverflow.com/questions/56911619/how-to-have-sanic-respond-with-http-and-ws