Skip to content

Commit 38af61e

Browse files
sanic examples (long-polling only)
1 parent ea94110 commit 38af61e

File tree

7 files changed

+323
-0
lines changed

7 files changed

+323
-0
lines changed

examples/sanic/README.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Socket.IO sanic Examples
2+
========================
3+
4+
This directory contains example Socket.IO applications that are compatible with
5+
asyncio and the sanic framework. These applications require Python 3.5 or
6+
later.
7+
8+
Note that because sanic does not support the WebSocket protocol, the only
9+
transport is long-polling at this time.
10+
11+
app.py
12+
------
13+
14+
A basic "kitchen sink" type application that allows the user to experiment
15+
with most of the available features of the Socket.IO server.
16+
17+
latency.py
18+
----------
19+
20+
A port of the latency application included in the official Engine.IO
21+
Javascript server. In this application the client sends *ping* messages to
22+
the server, which are responded by the server with a *pong*. The client
23+
measures the time it takes for each of these exchanges and plots these in real
24+
time to the page.
25+
26+
This is an ideal application to measure the performance of the different
27+
asynchronous modes supported by the Socket.IO server.
28+
29+
Running the Examples
30+
--------------------
31+
32+
To run these examples, create a virtual environment, install the requirements
33+
and then run::
34+
35+
$ python app.py
36+
37+
or::
38+
39+
$ python latency.py
40+
41+
You can then access the application from your web browser at
42+
``http://localhost:8000``.

examples/sanic/app.html

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<title>Flask-SocketIO Test</title>
5+
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.min.js"></script>
6+
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
7+
<script type="text/javascript" charset="utf-8">
8+
$(document).ready(function(){
9+
namespace = '/test';
10+
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
11+
12+
socket.on('connect', function() {
13+
socket.emit('my event', {data: 'I\'m connected!'});
14+
});
15+
socket.on('disconnect', function() {
16+
$('#log').append('<br>Disconnected');
17+
});
18+
socket.on('my response', function(msg) {
19+
$('#log').append('<br>Received: ' + msg.data);
20+
});
21+
22+
// event handler for server sent data
23+
// the data is displayed in the "Received" section of the page
24+
// handlers for the different forms in the page
25+
// these send data to the server in a variety of ways
26+
$('form#emit').submit(function(event) {
27+
socket.emit('my event', {data: $('#emit_data').val()});
28+
return false;
29+
});
30+
$('form#broadcast').submit(function(event) {
31+
socket.emit('my broadcast event', {data: $('#broadcast_data').val()});
32+
return false;
33+
});
34+
$('form#join').submit(function(event) {
35+
socket.emit('join', {room: $('#join_room').val()});
36+
return false;
37+
});
38+
$('form#leave').submit(function(event) {
39+
socket.emit('leave', {room: $('#leave_room').val()});
40+
return false;
41+
});
42+
$('form#send_room').submit(function(event) {
43+
socket.emit('my room event', {room: $('#room_name').val(), data: $('#room_data').val()});
44+
return false;
45+
});
46+
$('form#close').submit(function(event) {
47+
socket.emit('close room', {room: $('#close_room').val()});
48+
return false;
49+
});
50+
$('form#disconnect').submit(function(event) {
51+
socket.emit('disconnect request');
52+
return false;
53+
});
54+
});
55+
</script>
56+
</head>
57+
<body>
58+
<h1>Flask-SocketIO Test</h1>
59+
<h2>Send:</h2>
60+
<form id="emit" method="POST" action='#'>
61+
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
62+
<input type="submit" value="Echo">
63+
</form>
64+
<form id="broadcast" method="POST" action='#'>
65+
<input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
66+
<input type="submit" value="Broadcast">
67+
</form>
68+
<form id="join" method="POST" action='#'>
69+
<input type="text" name="join_room" id="join_room" placeholder="Room Name">
70+
<input type="submit" value="Join Room">
71+
</form>
72+
<form id="leave" method="POST" action='#'>
73+
<input type="text" name="leave_room" id="leave_room" placeholder="Room Name">
74+
<input type="submit" value="Leave Room">
75+
</form>
76+
<form id="send_room" method="POST" action='#'>
77+
<input type="text" name="room_name" id="room_name" placeholder="Room Name">
78+
<input type="text" name="room_data" id="room_data" placeholder="Message">
79+
<input type="submit" value="Send to Room">
80+
</form>
81+
<form id="close" method="POST" action="#">
82+
<input type="text" name="close_room" id="close_room" placeholder="Room Name">
83+
<input type="submit" value="Close Room">
84+
</form>
85+
<form id="disconnect" method="POST" action="#">
86+
<input type="submit" value="Disconnect">
87+
</form>
88+
<h2>Receive:</h2>
89+
<div><p id="log"></p></div>
90+
</body>
91+
</html>

examples/sanic/app.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import asyncio
2+
3+
from sanic import Sanic
4+
from sanic.response import html
5+
6+
import socketio
7+
8+
sio = socketio.AsyncServer(async_mode='sanic')
9+
app = Sanic()
10+
sio.attach(app)
11+
12+
13+
async def background_task():
14+
"""Example of how to send server generated events to clients."""
15+
count = 0
16+
while True:
17+
await sio.sleep(10)
18+
count += 1
19+
await sio.emit('my response', {'data': 'Server generated event'},
20+
namespace='/test')
21+
22+
23+
@app.route('/')
24+
async def index(request):
25+
with open('app.html') as f:
26+
return html(f.read())
27+
28+
29+
@sio.on('my event', namespace='/test')
30+
async def test_message(sid, message):
31+
await sio.emit('my response', {'data': message['data']}, room=sid,
32+
namespace='/test')
33+
34+
35+
@sio.on('my broadcast event', namespace='/test')
36+
async def test_broadcast_message(sid, message):
37+
await sio.emit('my response', {'data': message['data']}, namespace='/test')
38+
39+
40+
@sio.on('join', namespace='/test')
41+
async def join(sid, message):
42+
sio.enter_room(sid, message['room'], namespace='/test')
43+
await sio.emit('my response', {'data': 'Entered room: ' + message['room']},
44+
room=sid, namespace='/test')
45+
46+
47+
@sio.on('leave', namespace='/test')
48+
async def leave(sid, message):
49+
sio.leave_room(sid, message['room'], namespace='/test')
50+
await sio.emit('my response', {'data': 'Left room: ' + message['room']},
51+
room=sid, namespace='/test')
52+
53+
54+
@sio.on('close room', namespace='/test')
55+
async def close(sid, message):
56+
await sio.emit('my response',
57+
{'data': 'Room ' + message['room'] + ' is closing.'},
58+
room=message['room'], namespace='/test')
59+
await sio.close_room(message['room'], namespace='/test')
60+
61+
62+
@sio.on('my room event', namespace='/test')
63+
async def send_room_message(sid, message):
64+
await sio.emit('my response', {'data': message['data']},
65+
room=message['room'], namespace='/test')
66+
67+
68+
@sio.on('disconnect request', namespace='/test')
69+
async def disconnect_request(sid):
70+
await sio.disconnect(sid, namespace='/test')
71+
72+
73+
@sio.on('connect', namespace='/test')
74+
async def test_connect(sid, environ):
75+
await sio.emit('my response', {'data': 'Connected', 'count': 0}, room=sid,
76+
namespace='/test')
77+
78+
79+
@sio.on('disconnect', namespace='/test')
80+
def test_disconnect(sid):
81+
print('Client disconnected')
82+
83+
84+
app.static('/static', './static')
85+
86+
87+
if __name__ == '__main__':
88+
sio.start_background_task(background_task)
89+
app.run()

examples/sanic/latency.html

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Socket.IO Latency</title>
5+
<link rel="stylesheet" href="/static/style.css" />
6+
</head>
7+
<body>
8+
<h1>Socket.IO Latency <span id="latency"></span></h1>
9+
<h2 id="transport">(connecting)</h2>
10+
<canvas id="chart" height="200"></canvas>
11+
12+
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
13+
<script src="//cdnjs.cloudflare.com/ajax/libs/smoothie/1.27.0/smoothie.js"></script>
14+
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
15+
<script>
16+
// socket
17+
var socket = io.connect('http://' + document.domain + ':' + location.port);
18+
var char = $('chart').get(0);
19+
socket.on('connect', function() {
20+
if (chart.getContext) {
21+
render();
22+
window.onresize = render;
23+
}
24+
send();
25+
});
26+
socket.on('pong_from_server', function() {
27+
var latency = new Date - last;
28+
$('#latency').text(latency + 'ms');
29+
if (time)
30+
time.append(+new Date, latency);
31+
setTimeout(send, 100);
32+
});
33+
socket.on('disconnect', function() {
34+
if (smoothie)
35+
smoothie.stop();
36+
$('#transport').text('(disconnected)');
37+
});
38+
39+
var last;
40+
function send() {
41+
last = new Date;
42+
socket.emit('ping_from_client');
43+
$('#transport').text(socket.io.engine.transport.name);
44+
}
45+
46+
// chart
47+
var smoothie;
48+
var time;
49+
function render() {
50+
if (smoothie)
51+
smoothie.stop();
52+
chart.width = document.body.clientWidth;
53+
smoothie = new SmoothieChart();
54+
smoothie.streamTo(chart, 1000);
55+
time = new TimeSeries();
56+
smoothie.addTimeSeries(time, {
57+
strokeStyle: 'rgb(255, 0, 0)',
58+
fillStyle: 'rgba(255, 0, 0, 0.4)',
59+
lineWidth: 2
60+
});
61+
}
62+
</script>
63+
</body>
64+
</html>

examples/sanic/latency.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from sanic import Sanic
2+
from sanic.response import html
3+
4+
import socketio
5+
6+
sio = socketio.AsyncServer(async_mode='sanic')
7+
app = Sanic()
8+
sio.attach(app)
9+
10+
11+
@app.route('/')
12+
def index(request):
13+
with open('latency.html') as f:
14+
return html(f.read())
15+
16+
17+
@sio.on('ping_from_client')
18+
async def ping(sid):
19+
await sio.emit('pong_from_server', room=sid)
20+
21+
app.static('/static', './static')
22+
23+
24+
if __name__ == '__main__':
25+
app.run()

examples/sanic/requirements.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
aiofiles==0.3.0
2+
httptools==0.0.9
3+
python_engineio
4+
python_socketio
5+
sanic==0.3.1
6+
six==1.10.0
7+
ujson==1.35
8+
uvloop==0.8.0

examples/sanic/static/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
body { margin: 0; padding: 0; font-family: Helvetica Neue; }
2+
h1 { margin: 100px 100px 10px; }
3+
h2 { color: #999; margin: 0 100px 30px; font-weight: normal; }
4+
#latency { color: red; }

0 commit comments

Comments
 (0)