Commit bfd78b2a authored by Iván Amat's avatar Iván Amat

Upload files

# WebSocket based chat application
## Introduction
This is a simple websocket based chat server writed in python with a simple html chat client.
This is a learning project to test socketio, among other libraries. This project can be in continuous development, can end up being a complete chat or another type of application completely different from the current one.
## Prerequisites
* [flask](
* [socketio](
* [eventlet](
* [redis](
### Installation
pip install flask
pip install socketio
pip install eventlet
pip install redis
#### Redis Server
On Debian/Ubuntu
apt-get install redis-server
## Download
Download compressed files (master)
Download [.zip](
Download [.tar.gz](
Download [.tar.bz2](
Download [.tar](
.. or clone
git clone
## Running the Application
bin/websockets [arguments]
*Currently no arguments are accepted.
## Demo
[Launch the demo!](
## Changelog
### v0.0.2
* Store chat history on redis database server.
* Parse and show elements like links, email and images.
* User status (online/away). Detects whether the focus is on the window and the tab.
* Web Notifications: Show a web notification when receiving an event with the chat in the background (User away).
* Change the title of the web page when the user has unread messages. Adds the number of unread messages.
### v0.0.1
* Basic chat websocket server written in python.
* Basic client websocket written in html and javascript.
## Author
Iván Amat
\ No newline at end of file
BINPATH=`dirname $0`
python "$BINPATH/../websockets/" $@
@Echo OFF
set BINPATH=%~dp0
python "%BINPATH%..\websockets\" %*
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from options import Options
\ No newline at end of file
from argparse import ArgumentParser
class Options:
def __init__(self):
def _init_parser(self):
usage = 'bin/project'
self.parser = ArgumentParser(usage=usage)
help='An example option')
def parse(self, args=None):
return self.parser.parse_args(args)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys, json
import socketio, redis
import eventlet
import eventlet.wsgi
from flask import Flask, render_template
sio = socketio.Server()
app = Flask(__name__, static_folder='templates', static_url_path='')
app.config['DEBUG'] = False
db = redis.StrictRedis()
# HTML Chat client
def index():
return render_template('websockets.html')
# On user connect
@sio.on('connect', namespace='/chat')
def handle_connect(sid, environ):
print sid, " connected!"
msgs = db.lrange('messages',0,100)
sio.emit('db', msgs, namespace='/chat')
# On message received
@sio.on('message', namespace='/chat')
def message(sid, data):
db.lpush('messages', data);
# Decode json data
msg = json.loads(data)
# Emit message to all users, inside "/chat" namespace, in JSON format
# Read this:
if msg['type'] == 'system':
sio.emit('message', {'type': 'system', 'message': msg['message'], 'name': msg['name'], 'color': msg['color']}, namespace='/chat')
sio.emit('message', {'type': 'usermsg', 'message': msg['message'], 'name': msg['name'], 'color': msg['color']}, namespace='/chat')
if __name__ == '__main__':
# Get PID
pid = str(os.getpid())
pidfile = "/tmp/"
# If the program is running, do not continue with the program starting.
if os.path.isfile(pidfile):
print "%s already exists!" % pidfile
print "The program is already running!"
print "Exiting..."
# Generate PID file
file(pidfile, 'w').write(pid)
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 5050)), app)
This diff is collapsed.
<!DOCTYPE html>
<html lang="es">
<meta charset="utf-8">
<title>WebSocket based chat application</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />
<link rel="stylesheet" href="" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />
<link rel="stylesheet" href="ws.css" />
<script type="text/javascript" src="jquery-3.1.1.js" charset="utf-8"></script>
<script type="text/javascript" src="//" charset="utf-8"></script>
<script type="text/javascript" src="" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script type="text/javascript" src="ws.js" charset="UTF-8"></script>
<h1 class="text-center">WebSocket based chat application</h1>
<hr />
<main class="container">
<section class="row">
<div class="col-md-12">
<h2 class="client_title pull-left">HTML Client</h2>
<p class="code text-right"><a href="" class="sourcecode" target="_blank">python</a> | <a href="" class="sourcecode" target="_blank">html</a> | <a href="" class="sourcecode" target="_blank">css</a> | <a href="" class="sourcecode" target="_blank">js</a></p>
<div class="clearfix"></div>
<div class="panel panel-default">
<div class="panel-body">
<div class="chat_wrapper">
<div class="message_box" id="message_box"></div><!-- Messsages box -->
<div class="input-group">
<input type="text" name="message" id="message" placeholder="Message..." onkeydown="if (event.keyCode == 13)document.getElementById('send-btn').click()" class="form-control" /><!-- Text input -->
<span class="input-group-btn">
<button id="send-btn" class="btn btn-default" type="button">Send!</button><!-- Send button -->
<section class="row">
<div class="col-md-12 text-center">
<h2>About WebSocket based chat application</h2>
<p>A simple websocket based chat server writed in python with a simple html chat client.</p>
<p>You can <b>download</b> the code from <a class="sourcecode" href="" target="_blank"></a></p>
<p>Visit <a id="author" href="" target="_blank"></a></p>
\ No newline at end of file
html,body {
cursor: default;
.panel-default {
background: #ececec;
.chat_wrapper .message_box {
background: #F7F7F7;
overflow: auto;
padding: 10px 10px 0px 10px;
border: 1px solid #ccc;
margin-bottom: 16px;
border: 2px solid #ececec;
padding: 20px;
resize: vertical;
overflow: auto;
.code {width:200px;float:right;margin:0px;padding:0px;margin-bottom:3px;}
.code a {font-size:14px;line-height:14px;color:#000000;}
.code a:hover {color:#848484;}
.system_msg{color:#BDBDBD;font-style: italic;}
.user_message{color: #686868;}
.frame {
width: 960px;
height: 540px;
width: 480px;
height: 270px;
.frame frame {
width: 960px;
height: 540px;
border: none;
-moz-transform: scale(0.2);
-moz-transform-origin: 0 0;
-o-transform: scale(0.2);
-o-transform-origin: 0 0;
-webkit-transform: scale(0.2);
-webkit-transform-origin: 0 0;
.system_msg.image {
max-width: 240px;
padding: 8px;
margin-top: 6px;
margin-bottom: 6px;
background: #ececec;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
.system_msg.image span.user_name {
margin-bottom: 5px;
display: block;
.system_msg.image img {
max-width: 100%;
height: auto;
@media only screen and (max-width: 720px) {
/* For mobile phones: */
.chat_wrapper {
width: 100%;
height: 40%;
\ No newline at end of file
This diff is collapsed.
import sys
from main import app as application
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment