Skip to content

Instantly share code, notes, and snippets.

@marians
Created May 12, 2015 14:47
Show Gist options
  • Save marians/682711d839c2d6066b5e to your computer and use it in GitHub Desktop.
Save marians/682711d839c2d6066b5e to your computer and use it in GitHub Desktop.
Giant Swarm Websocket example

To run this, do

# Create docker image
docker build -t registry.giantswarm.io/<your-organization>/<your-imagename> .

# test docker image locally
docker run --rm -ti -p 5000:5000 registry.giantswarm.io/<your-organization>/<your-imagename>

# now open your Docker IP on port 5000 in a browser

# login only of not yet logged in on private docker registry
docker login https://registry.giantswarm.io
docker push registry.giantswarm.io/<your-organization>/<your-imagename>

# login with swarm only of not logged on before
swarm login <your-username>

swarm env <your-organization>/<your-envname>
swarm create
swarm start
FROM python:2.7-slim
ENV DEBIAN_FRONTEND noninteractive
RUN set -x \
&& apt-get -q update \
&& apt-get install -yq --no-install-recommends git-core build-essential \
&& pip install cython \
&& pip install git+https://github.com/gevent/gevent.git#egg=gevent \
&& pip install Flask \
&& pip install flask-socketio \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false -o APT::AutoRemove::SuggestsImportant=false build-essential \
&& rm -rf /var/lib/apt/lists/*
COPY server.py /
ADD templates /templates
ENTRYPOINT ["python", "-u", "/server.py"]
EXPOSE 5000
<!DOCTYPE HTML>
<html>
<head>
<!--
This file belongs into /templates/index.html
Copied from https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example
(Copyright (c) 2014 Miguel Grinberg, licensed under the MIT license)
-->
<title>Flask-SocketIO Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
namespace = '/test'; // change to an empty string to use the global namespace
// the socket.io documentation recommends sending an explicit package upon connection
// this is specially important when using the global namespace
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
socket.on('connect', function() {
socket.emit('my event', {data: 'I\'m connected!'});
});
// event handler for server sent data
// the data is displayed in the "Received" section of the page
socket.on('my response', function(msg) {
$('#log').append('<br>Received #' + msg.count + ': ' + msg.data);
});
// handlers for the different forms in the page
// these send data to the server in a variety of ways
$('form#emit').submit(function(event) {
socket.emit('my event', {data: $('#emit_data').val()});
return false;
});
$('form#broadcast').submit(function(event) {
socket.emit('my broadcast event', {data: $('#broadcast_data').val()});
return false;
});
$('form#join').submit(function(event) {
socket.emit('join', {room: $('#join_room').val()});
return false;
});
$('form#leave').submit(function(event) {
socket.emit('leave', {room: $('#leave_room').val()});
return false;
});
$('form#send_room').submit(function(event) {
socket.emit('my room event', {room: $('#room_name').val(), data: $('#room_data').val()});
return false;
});
$('form#close').submit(function(event) {
socket.emit('close room', {room: $('#close_room').val()});
return false;
});
$('form#disconnect').submit(function(event) {
socket.emit('disconnect request');
return false;
});
});
</script>
</head>
<body>
<h1>Flask-SocketIO Test</h1>
<h2>Send:</h2>
<form id="emit" method="POST" action='#'>
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
<input type="submit" value="Echo">
</form>
<form id="broadcast" method="POST" action='#'>
<input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
<input type="submit" value="Broadcast">
</form>
<form id="join" method="POST" action='#'>
<input type="text" name="join_room" id="join_room" placeholder="Room Name">
<input type="submit" value="Join Room">
</form>
<form id="leave" method="POST" action='#'>
<input type="text" name="leave_room" id="leave_room" placeholder="Room Name">
<input type="submit" value="Leave Room">
</form>
<form id="send_room" method="POST" action='#'>
<input type="text" name="room_name" id="room_name" placeholder="Room Name">
<input type="text" name="room_data" id="room_data" placeholder="Message">
<input type="submit" value="Send to Room">
</form>
<form id="close" method="POST" action="#">
<input type="text" name="close_room" id="close_room" placeholder="Room Name">
<input type="submit" value="Close Room">
</form>
<form id="disconnect" method="POST" action="#">
<input type="submit" value="Disconnect">
</form>
<h2>Receive:</h2>
<div id="log"></div>
</body>
</html>
# Adapted from https://github.com/miguelgrinberg/Flask-SocketIO/tree/master/example
# (Copyright (c) 2014 Miguel Grinberg, licensed under the MIT license)
import time
from threading import Thread
from flask import Flask, render_template, session, request
from flask.ext.socketio import SocketIO, emit, join_room, leave_room, \
close_room, disconnect
app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'Very secret'
socketio = SocketIO(app)
thread = None
def background_thread():
"""Example of how to send server generated events to clients."""
count = 0
while True:
time.sleep(10)
count += 1
socketio.emit('my response',
{'data': 'Server generated event', 'count': count},
namespace='/test')
@app.route('/')
def index():
global thread
if thread is None:
thread = Thread(target=background_thread)
thread.start()
return render_template('index.html')
@socketio.on('my event', namespace='/test')
def test_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': message['data'], 'count': session['receive_count']})
@socketio.on('my broadcast event', namespace='/test')
def test_broadcast_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': message['data'], 'count': session['receive_count']},
broadcast=True)
@socketio.on('join', namespace='/test')
def join(message):
join_room(message['room'])
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': 'In rooms: ' + ', '.join(request.namespace.rooms),
'count': session['receive_count']})
@socketio.on('leave', namespace='/test')
def leave(message):
leave_room(message['room'])
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': 'In rooms: ' + ', '.join(request.namespace.rooms),
'count': session['receive_count']})
@socketio.on('close room', namespace='/test')
def close(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response', {'data': 'Room ' + message['room'] + ' is closing.',
'count': session['receive_count']},
room=message['room'])
close_room(message['room'])
@socketio.on('my room event', namespace='/test')
def send_room_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': message['data'], 'count': session['receive_count']},
room=message['room'])
@socketio.on('disconnect request', namespace='/test')
def disconnect_request():
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my response',
{'data': 'Disconnected!', 'count': session['receive_count']})
disconnect()
@socketio.on('connect', namespace='/test')
def test_connect():
emit('my response', {'data': 'Connected', 'count': 0})
@socketio.on('disconnect', namespace='/test')
def test_disconnect():
print('Client disconnected')
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0')
{
"app_name": "websockets",
"services": [
{
"service_name": "server",
"components": [
{
"component_name": "server",
"image": "registry.giantswarm.io/<your-organization>/<your-imagename>",
"ports": [5000],
"domains": {
"<your-sub-domain>.gigantic.io": 5000
}
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment