I've set up a very basic websocket server using tornado:
import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.httpserver
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print 'new connection'
self.write_message("Hello World")
def on_message(self, message):
print 'message received %s' % message
def on_close(self):
print 'connection closed'
application = tornado.web.Application([
(r'/ws', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8000)
tornado.ioloop.IOLoop.instance().start()
and a very basic client, that should be able to continually ping the server via a button click:
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://localhost:8000/ws";
var websocket = new WebSocket(wsUri);
var output;
function init() {
output = document.getElementById("outputDiv");
if (!'WebSocket' in window){
writeToScreen('<span style="color: red;">ERROR: Update your browser to one that supports websockets. A list can be found <a href="http://caniuse.com/websockets">here</a></span>');
} else {
testWebSocket();
}
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("Hi there!");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
websocket.close();
}
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
function testWebSocket() {
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
document.getElementById("send").onclick = function () {
doSend(document.getElementById("inputTxt").value);
console.log("click registered.");
};
}
window.addEventListener("load", init, false);
</script>
</div>
<h2>WebSocket Test</h2>
<div id="inputDiv">
<input id="inputTxt" type="text"/>
<button id="send" onclick=>send</button>
</div>
<div id="outputDiv">
</div>
</html>
When I load the page, I get:
CONNECTED
SENT: Hi there!
RESPONSE: Hello World
DISCONNECTED
If I click the button, I get an error:
WebSocket is already in CLOSING or CLOSED state.
But, if I re-instantiate the websocket object in the command line (via chrome developer tools), the button works, and the connection is not closed. I feel that this must be some idiosyncrasy of javascript that I don't understand, because if the object is still in scope, I don't understand why it would have automatically closed the connection.
This is likely due to client security rules in the WebSocket spec to prevent abusing WebSocket. (such as using it to scan for open ports on a destination server, or for generating lots of connections for a denial-of-service attack).
Unlike HTTP connections, WebSocket connections stay open, or. This is also known as a publish-subscribe messaging pattern: the client can “subscribe” to the server and whenever the server “publishes” a message, the subscribers are notified.
However, the connection between a client and your WebSocket app closes when no traffic is sent between them for 60 seconds.
Derp. The onMessage function is closing it:
function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
websocket.close();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With