POST /login/
HTTP/1.1 200 OK You are logged in!
POST /login/
HTTP/1.1 200 OK You are logged in!
"Hey the fox is logged in"
"Hey the fox is logged in"
POST /login/
HTTP/1.1 200 OK You are logged in!
"Hey the fox is logged in"
"Hey the fox is logged in"
How to?
GET /userlist/
GET /userlist/
GET /userlist/
Client periodically issues request to the server
(e.g. every second)
GET /next-connected/
GET /next-connected/
The server does not respond immediately, it keeps the connection open.
GET /next-connected/
POST /login/
GET /next-connected/
POST /login/
"Opera is logged in!"
GET /next-connected/
GET /next-connected/
The client has received a response, it opens a new connection
GET /next-connected/
GET /next-connected/
POST /login/
GET /next-connected/
GET /next-connected/
POST /login/
"Chrome is logged in!"
GET /app/socket HTTP/1.1 Upgrade: websocket Connection: Upgrade
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade
WS (or WSS) channel
User connection
POST /login/
User connection
"Opera is logged in"
"Opera is logged in"
"Opera is logged in"
User connection
Real time game
"I've hit the left arrow"
Real time game
"I've hit the left arrow"
Chrome's position is (10, 50)
Chrome's position is (10, 50)
Real time game
Chrome's position is (10, 50)
Instant messaging
Instant messaging
"Hi Firefox!"
Instant messaging
"Hi Firefox!"
"Chrome said: 'Hi Firefox!' "
pip install flask-socketio
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
Http request
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
WS channel,
on connection
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
channel we are emitting on
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
channel we are emitting on
Data we are sending (translated to JSON)
from flask import Flask
import flask_socketio
app = Flask(__name__)
io = flask_socketio.SocketIO(app)
@app.route("/")
@flask_login.login_required
def home():
return render_template('index.html')
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
channel we are emitting on
Data we are sending (translated to JSON)
Send to all users
"Opera is logged in"
"Opera is logged in"
"Opera is logged in"
User connection
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('userlist', function(users){
set_userlist(users);
});
</script>
server.py
index.html
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('userlist', function(users){
set_userlist(users);
});
</script>
server.py
index.html
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('userlist', function(users){
set_userlist(users);
});
</script>
server.py
index.html
@io.on('connect')
def ws_connect():
io.emit('userlist', [
"Arthur",
"Zaphod",
],
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('userlist', function(users){
set_userlist(users);
});
</script>
server.py
index.html
"Opera is logged in"
"Opera is logged in"
"Opera is logged in"
User connection
"I've hit the left arrow"
Chrome's position is (10, 50)
Chrome's position is (10, 50)
Real time game
Chrome's position is (10, 50)
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
server.py
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
Fake syntaxe, more on that later
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
@io.on('move')
def handle_move(movement):
current_user.go_to(movement)
io.emit('new_position', {
"user": current_user.id,
"position": current_user.position,
},
broadcast=True
)
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('new_position', function(data){
players[data.user].position = data.position
});
<on new move>(function(movement) {
socket.emit('move', movement);
});
server.py
index.html
"I've hit the left arrow"
Chrome's position is (10, 50)
Chrome's position is (10, 50)
Real time game
Chrome's position is (10, 50)
WebSocket
Ports
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
index.html
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
port move: String -> Cmd msg
-- ...
-- in update:
LeftArrowPressed ->
( model, move "Left")
RightArrowPressed ->
( model, move "Right")
index.html
Main.elm
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
port move: String -> Cmd msg
-- ...
-- in update:
LeftArrowPressed ->
( model, move "Left")
RightArrowPressed ->
( model, move "Right")
index.html
Main.elm
Elm to JS port
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
port move: String -> Cmd msg
-- ...
-- in update:
LeftArrowPressed ->
( model, move "Left")
RightArrowPressed ->
( model, move "Right")
index.html
Main.elm
Elm to JS port
JS code subscribes to Elm "events"
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
port move: String -> Cmd msg
-- ...
-- in update:
LeftArrowPressed ->
( model, move "Left")
RightArrowPressed ->
( model, move "Right")
index.html
Main.elm
JS code subscribes to Elm "events"
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
index.html
port newPosition: (PosData -> msg) -> Sub msg
type Msg
= GotNewPosition PosData
| ...
subscriptions model =
newPosition GotNewPosition
Main.elm
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
index.html
port newPosition: (PosData -> msg) -> Sub msg
type Msg
= GotNewPosition PosData
| ...
subscriptions model =
newPosition GotNewPosition
Main.elm
JS to Elm port
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
index.html
port newPosition: (PosData -> msg) -> Sub msg
type Msg
= GotNewPosition PosData
| ...
subscriptions model =
newPosition GotNewPosition
Main.elm
JS to Elm port
Elm code subscribes to JS events
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: foo});
socket.on('new_position', function(data){
app.ports.newPosition.send(data);
});
app.ports.move.subscribe(function(movement) {
socket.emit('move', movement);
});
index.html
port newPosition: (PosData -> msg) -> Sub msg
type Msg
= GotNewPosition PosData
| ...
subscriptions model =
newPosition GotNewPosition
Main.elm
Elm code subscribes to JS events
port newPosition: (PosData -> msg) -> Sub msg
type Msg
= GotNewPosition PosData
| ...
subscriptions model =
newPosition GotNewPosition
type alias PosData =
{ user: String, position: (Int, Int) }
-- in update:
GotNewPosition posData ->
( setNewPos posData model, Cmd.none)
setNewPos : PosData -> Model -> Model
setNewPos posData model =
...