Skip to content

Instantly share code, notes, and snippets.

@mmaridev
Last active December 12, 2018 16:16
Show Gist options
  • Save mmaridev/7f280fef7db12fc0ee04724a27b81ffb to your computer and use it in GitHub Desktop.
Save mmaridev/7f280fef7db12fc0ee04724a27b81ffb to your computer and use it in GitHub Desktop.
Chat client based on twisted/autobahn (without history)
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script type="text/javascript">
// Use vanilla JS because why not xD
var mySocket;
$(document).ready(function() {
$("#chatting").hide();
// Create the websocket instance.
window.mySocket = new WebSocket("ws://localhost:8081");
// Add an event listener reacting when message is received
window.mySocket.onmessage = function (event) {
var data = JSON.parse(event.data);
var me = $("#user").val();
var attrs = "alert alert-warning";
var msg = data["msg"];
if (data["from"] == me) {
attrs = "alert alert-success text-right";
}
else {
msg = "<b>" + data["from"] + "</b>: " + data["msg"]
}
var chatbox = $("#output");
var alert = "<div class='" + attrs + "' role='alert'>";
alert += msg;
alert += "</div>";
chatbox.prepend(alert);
/*
var output = document.getElementById("output");
// Put message into our output div on its first line.
var lastMessage = output.firstChild
var newMessage = document.createElement("p");
var messageContent = document.createTextNode(event.data);
console.log(event.data);
newMessage.appendChild(messageContent);
output.insertBefore(newMessage, lastMessage);*/
//output.textContent = event.data;
};
$("#start").click(function () {
$("#pagetitle").text("Thin (bugged) chat client - Logged in as " + $("#user").val());
$("#pre").slideUp();
$("#chatting").slideDown();
});
function performSend() {
sending = {"user": $("#user").val(), "text": $("#input").val()};
window.mySocket.send(JSON.stringify(sending));
$("#input").val("");
}
$("#sendMessage").click(performSend);
$("#input").keyup(function(event) {
if (event.keyCode === 13) {performSend();}
});
});
</script>
<title>ThinChat Client</title>
</head>
<body>
<div class="container">
<div class="jumbotron">
<div id="pre" class="row">
<div class="col-lg-3 text-center">Nickname:</div>
<div class="col-lg-6 text-center"><input type="text" class="btn-block" id="user" /></div>
<div class="col-lg-3 text-center">
<a href="#" class="btn btn-lg btn-block btn-warning" style="color:white;" id="start">
Start chatting! <i class="fas fa-arrow-right" aria-hidden="true"></i>
</a>
</div>
</div>
<div id="chatting">
<h1><b id="pagetitle">Thin (bugged) chat client</b></h1><br>
<form class="chat" id="chatForm">
<div class="row">
<div class="col-lg-10">
<input id="input" class="btn-block"></input>
</div>
<div class="col-lg-2">
<input type="button" class="btn btn-lg btn-info btn-block" id="sendMessage" value="Send">
</div>
</div>
</form>
<br>
<div id="output"></div>
</div>
</div>
</div>
</body>
</html>
#!/usr/bin/python3
# This is a script written as homework for computer science
# (c) 2018 Marco Marinello <mmarinello@sezf.it>
import sys
import cgi
from twisted.web.static import File
from twisted.python import log
from twisted.web.server import Site
from twisted.internet import reactor
from autobahn.twisted.websocket import WebSocketServerFactory, \
WebSocketServerProtocol, listenWS
from autobahn.twisted.resource import WebSocketResource
import json
import inspect
WEB_HOST = "localhost"
WEB_PORT = 8080
WS_PROTO = "ws:"
WS_PORT = 8081
# Code from autobahn's github for broadcast
class BroadcastServerFactory(WebSocketServerFactory):
"""
Simple broadcast server broadcasting any message it receives to all
currently connected clients.
"""
def __init__(self, url):
WebSocketServerFactory.__init__(self, url)
self.clients = []
self.tickcount = 0
def register(self, client):
if client not in self.clients:
print("registered client {}".format(client.peer))
self.clients.append(client)
def unregister(self, client):
if client in self.clients:
print("unregistered client {}".format(client.peer))
self.clients.remove(client)
def broadcast(self, msg):
print("broadcasting message '{}' ..".format(msg))
for c in self.clients:
c.sendMessage(msg.encode('utf8'))
print("message sent to {}".format(c.peer))
# Handle web socket messages.
class ChatServerProtocol(WebSocketServerProtocol):
def onOpen(self):
self.factory.register(self)
def connectionLost(self, reason):
WebSocketServerProtocol.connectionLost(self, reason)
self.factory.unregister(self)
def onConnect(self, request):
print("some request connected {}".format(request))
def onMessage(self, payload, isBinary):
if isBinary is False:
try:
data = json.loads(payload.decode("utf-8"))
response = {
"from": data["user"],
"msg": data["text"]
}
response = json.dumps(response, ensure_ascii = False)
except Exception as e:
print(e)
response = {
"from": "sysadmin",
"msg": "ERROR: Unable to parse JSON from the request"
}
response = json.dumps(response, ensure_ascii = False)
#print(response)
self.factory.broadcast(response)
else:
pass
log.startLogging(sys.stdout)
ServerFactory = BroadcastServerFactory
# Serve WebSockets.
webSocketHost = str(WS_PROTO) + "//" + str(WEB_HOST) + ":" + str(WS_PORT)
webSock = ServerFactory(webSocketHost)
webSock.protocol = ChatServerProtocol
listenWS(webSock)
# Serve HTTP sites.
content = File(".") # index.html ect.
web = Site(content)
reactor.listenTCP(WEB_PORT, web)
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment