Skip to content
This repository has been archived by the owner on Feb 13, 2019. It is now read-only.

Commit

Permalink
improvements to demo, safe write message
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Jun 1, 2015
1 parent 2de93f8 commit 3212e8c
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 66 deletions.
56 changes: 56 additions & 0 deletions demo/demoapp/static/js/ws.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
$(document).ready(function(){
if (!('WebSocket' in window)) {
alert('WebSockets are not supported by your browser.');
return;
}

var ws = null;

function close(){
log('closing connection...');
ws.close();
ws = null;
}
$('#close').click(close);

function open(){
if (ws !== null){
close();
}
var url = djws.ws_url;
log('connecting to "' + url + '" with token "' + djws.token + '"...');
ws = new WebSocket(url, djws.token);

ws.onopen = function(){
log('connected');
};

ws.onmessage = function (evt) {
log('< ' + evt.data);
};

ws.onclose = function (evt) {
log('Connection closed, reason: "' + evt.reason + '", code: ' + evt.code);
console.log('close event:', evt);
};
}
$('#open').click(open);
open();

$('#user-input').submit(function (e){
e.preventDefault();
var msg = $msg_box.val();
log('> '+ msg);
ws.send(msg);
$msg_box.val('');
});
});

var $console = $('#console');
var $msg_box = $('#message-box');

function log(message){
$console.append(message + '\n');
console.log(message);
$console[0].scrollTop = $console.height();
}
2 changes: 1 addition & 1 deletion demo/demoapp/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1>{{ title }}</h1>
{% for message in messages %}
<div class="alert alert-{% if message.tags == 'error' %}danger{% else %}{{ message.tags }}{% endif %}">
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">&times;</span>
<span>&times;</span>
<span class="sr-only">Close</span>
</button>
{{ message }}
Expand Down
15 changes: 9 additions & 6 deletions demo/demoapp/templates/wsconn.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,20 @@
</div>
</div>
<div class="col-md-6">
{% if user %}
<p>You are logged in as {{ user }}</p>
{% endif %}
<dl class="dl-horizontal">
<dt>pingpong</dt><dd>prompt ping pong from server to find response time</dd>
<dt>clients</dt><dd>Get information about all clients connected to this server</dd>
<dt>*</dt><dd>Anything else will be echoed to all clients</dd>
</dl>
<form id="user-input">
<div class="form-group">
<input type="text" class="form-control" id="message-box" placeholder="send raw message..."/>
</div>
<div class="form-group">
<input type="submit" class="btn btn-default" value="send"/>
<div class="input-group">
<input type="text" class="form-control" id="message-box" placeholder="say something..."/>
<span class="input-group-btn">
<input type="submit" class="btn btn-default" value="send"/>
</span>
</div>
</form>
</div>
Expand All @@ -46,5 +49,5 @@
{% load websockets %}
{% websocket_info ws_url %}
{% load staticfiles %}
<script src="{% static 'js/debug.js' %}"></script>
<script src="{% static 'js/ws.js' %}"></script>
{% endblock %}
5 changes: 4 additions & 1 deletion demo/demoapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ def get_context_data(self, **kwargs):
user = authenticate(username=user.username, password='anything')
login(self.request, user)
messages.info(self.request, 'Creating you as new user %s and logging you in' % self.request.user)
else:
user = self.request.user
kwargs.update(
title='django-websockets authenticated users',
ws_url='auth'
ws_url='auth',
user=user
)
return super(IndexView, self).get_context_data(**kwargs)

Expand Down
31 changes: 16 additions & 15 deletions demo/demoapp/ws_handlers.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
from tornado.websocket import WebSocketClosedError
from django_websockets.handlers import AnonSocketHandler, AuthSocketHandler, PingPongMixin, all_clients


class WsBase(PingPongMixin):
def open(self):
super(WsBase, self).open()
self.ping_timer()
try:
self.write_message('Clients Connected: %s' % all_clients.status)
self.write_message('connection user: %s' % self.user)
except WebSocketClosedError:
# this happens on authenticated connection due to selecting subprotocol (I assume?)
# we can safely ignore it
pass
self.safe_write_message('Clients Connected: %s' % all_clients.status)
self.broadcast('new user connected: %s' % self.user)

def pong_time_handler(self, response_time):
self.write_message('ping pong time: %0.2fms' % response_time)
self.safe_write_message('ping pong time: %0.2fms' % response_time)

def on_message(self, data):
if data == 'pingpong':
self.ping_timer()
elif data == 'clients':
self.write_message('Clients Connected: %s' % all_clients.status)
self.safe_write_message('Clients Connected: %s' % all_clients.status)
else:
msg = 'msg from %s: %s' % (self.user, data)
for cli in all_clients:
if cli.ws_connection is not None:
cli.write_message(msg)
if any(ord(x) > 255 for x in data[:50]):
msg = 'binary data length %d' % len(data)
else:
msg = data
self.broadcast('%s: %s' % (self.user or 'anon', msg))

def broadcast(self, msg):
for cli in all_clients:
cli.safe_write_message(msg)


class AnonEchoHandler(WsBase, AnonSocketHandler):
pass
def open(self):
self.user = 'anon %s' % str(hash(self))[-7:]
super(AnonEchoHandler, self).open()


class AuthEchoHandler(WsBase, AuthSocketHandler):
Expand Down
13 changes: 11 additions & 2 deletions django_websockets/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ def on_close(self):
logger.debug('client disconnected, close code: %r, close reason: %r', self.close_code, self.close_reason)
all_clients.remove(self, not self._client_added)

def safe_write_message(self, data):
"""
wrapper for write_message which checks the underlying websocket connection is opening before sending
message to avoid WebSocketClosedError
:param data: data to send
"""
if self.ws_connection is not None:
self.write_message(data)


class AuthSocketHandler(AnonSocketHandler):
"""
Expand Down Expand Up @@ -183,7 +192,7 @@ def open(self):

def on_message(self, data):
logger.info('received message: %r' % data)
self.write_message(data)
self.safe_write_message(data)


class AuthEchoHandler(PingPongMixin, AuthSocketHandler):
Expand All @@ -196,4 +205,4 @@ def open(self):

def on_message(self, data):
logger.info('received message: %r' % data)
self.write_message(data)
self.safe_write_message(data)
41 changes: 0 additions & 41 deletions django_websockets/static/js/debug.js

This file was deleted.

0 comments on commit 3212e8c

Please sign in to comment.