read
In my CPSC350 course we learned about SocketIO. I really enjoyed the SocketIO assignment because I always wondered how a chatroom worked.
Although, I found the assignment to be one of my more difficult ones to complete, it was not to hard to figure out. Once I figured out how the data
is retreived and send between the functions I was easily able to complete the assignment. In the HTML file the Angular JS
directive sends information to the Javascript file which then passed the information to the Python file, the information then makes its way back
to the Javascript file and would then be outputted to the HTML file. Each socketio function in the Javascript file updates the screen without
consistently reloading the site, thus, quickly and efficiently displaying information to the user.
SocketIO Pt1 Rudiment:
Python File
#server.py
import os
import uuid
import psycopg2
import psycopg2 . extras
from flask import Flask , session
from flask . ext . socketio import SocketIO , emit
app = Flask ( __name__ , static_url_path = '' )
app . config [ 'SECRET_KEY' ] = 'secret!'
socketio = SocketIO ( app )
messages = []
users = {}
def connectToDB ():
connectionString = 'dbname=space user=astro password=astro123 host=localhost'
print connectionString
try:
return psycopg2 . connect ( connectionString )
except:
print ( "Can't connect to database" )
@socketio . on ( 'connect' , namespace = '/iss' )
def makeConnection ():
print ( 'connected' )
conn = connectToDB ()
cur = conn . cursor ( cursor_factory = psycopg2 . extras . DictCursor )
cur . execute ( "SELECT username, message FROM messages JOIN users ON messages.userid = users.id" )
msgs = cur . fetchall ()
conn . commit ()
session [ 'uuid' ] = uuid . uuid1 ()
for msg in msgs:
tmp = { 'text' :msg [ 'message' ], 'name' :msg [ 'username' ]}
emit ( 'message' , tmp )
@socketio . on ( 'identify' , namespace = '/iss' )
def on_identify ( person ):
print ( 'identify ' + person )
@socketio . on ( 'login' , namespace = '/iss' )
def on_login ( username , password ):
conn = connectToDB ()
cur = conn . cursor ( cursor_factory = psycopg2 . extras . DictCursor )
print ( 'login' + username + password )
session [ 'username' ] = username
users [ session [ 'uuid' ]] = { 'username' : username }
try:
query = cur . mogrify ( "SELECT * FROM users WHERE username = %s AND password = crypt(%s, password) " , ( users [ session [ 'uuid' ]][ 'username' ], password ))
cur . execute ( query )
results = cur . fetchall ()
conn . commit ()
print ( results )
#Check if there is a result
if ( cur . rowcount == 1 ):
print ( 'connected roster' )
print ( session [ 'uuid' ])
print ( users [ session [ 'uuid' ]][ 'username' ])
print ( "ida" )
emit ( 'loggedin' , users [ session [ 'uuid' ]][ 'username' ])
tmp = { 'text' :"is now connected" , 'name' :users [ session [ 'uuid' ]][ 'username' ]}
emit ( 'message' , tmp , broadcast = True )
#Incorrect password or not a user
else:
print ( "Invalid username or password!" )
conn . rollback ()
except:
print ( "Error logging in!" )
conn . rollback ()
conn . commit ()
@socketio . on ( 'message' , namespace = '/iss' )
def new_message ( message1 ):
conn = connectToDB ()
cur = conn . cursor ( cursor_factory = psycopg2 . extras . DictCursor )
try:
print ( users )
print ( session [ 'uuid' ])
print ( "idb" )
query = cur . mogrify ( """INSERT INTO messages(message, userid) VALUES(%s, (SELECT id FROM users WHERE username = %s))""" , ( message1 , users [ session [ 'uuid' ]][ 'username' ]))
print ( query )
cur . execute ( query )
conn . commit ()
tmp = { 'text' :message1 , 'name' : users [ session [ 'uuid' ]][ 'username' ]}
emit ( 'message' , tmp , broadcast = True )
except:
print ( "Error messaging!" )
conn . rollback ()
conn . commit ()
@socketio . on ( 'search' , namespace = '/iss' )
def search ( term ):
conn = connectToDB ()
cur = conn . cursor ( cursor_factory = psycopg2 . extras . DictCursor )
try:
print ( "hi" )
query = cur . mogrify ( "SELECT username, message FROM messages JOIN users ON messages.userid = users.id WHERE messages.message LIKE '%%%s%%' OR users.username LIKE '%%%s%%'" % ( term , term , ))
print ( query )
cur . execute ( query )
results = cur . fetchall ()
print ( results )
conn . commit ()
except:
print ( "error searching" )
conn . rollback ()
emit ( 'clear' )
for r in results:
tmp = { 'message1' :r [ 'message' ], 'user' :r [ 'username' ]}
emit ( 'found' , tmp )
@socketio . on ( 'disconnect' , namespace = '/chat' )
def on_disconnect ():
print 'disconnect'
@app . route ( '/' )
def mainIndex ():
print 'in hello world'
return app . send_static_file ( 'index.html' )
@app . route ( '/js/<path:path>' )
def static_proxy_js ( path ):
# send_static_file will guess the correct MIME type
return app . send_static_file ( os . path . join ( 'js' , path ))
@app . route ( '/css/<path:path>' )
def static_proxy_css ( path ):
# send_static_file will guess the correct MIME type
return app . send_static_file ( os . path . join ( 'css' , path ))
@app . route ( '/img/<path:path>' )
def static_proxy_img ( path ):
# send_static_file will guess the correct MIME type
return app . send_static_file ( os . path . join ( 'img' , path ))
# start the server
if __name__ == '__main__' :
socketio . run ( app , host = os . getenv ( 'IP' , '0.0.0.0' ), port = int ( os . getenv ( 'PORT' , 8080 )), debug = True )
SQL file
#space.sql
DROP DATABASE IF EXISTS space ;
CREATE DATABASE space ;
DROP ROLE IF EXISTS astro ;
CREATE ROLE astro WITH password 'astro123' LOGIN ;
\ c space
CREATE EXTENSION pgcrypto ;
DROP TABLE IF EXISTS users ;
CREATE TABLE users (
id serial NOT NULL ,
username text NOT NULL ,
password text NOT NULL ,
PRIMARY KEY ( id )
);
GRANT ALL ON users TO astro ;
GRANT ALL ON users_id_seq TO astro ;
DROP TABLE IF EXISTS messages ;
CREATE TABLE messages (
id serial NOT NULL ,
message varchar ( 256 ) NOT NULL ,
userid int NOT NULL ,
PRIMARY KEY ( id ),
CONSTRAINT user_id_fk
FOREIGN KEY ( userid )
REFERENCES users ( id )
);
GRANT ALL ON messages TO astro ;
GRANT ALL ON messages_id_seq TO astro ;
GRANT ALL ON messages_userid_seq TO astro ;
INSERT INTO users ( username , password ) VALUES ( 'chelsea' , crypt ( 'chelsea' , gen_salt ( 'bf' )));
INSERT INTO users ( username , password ) VALUES ( 'raz' , crypt ( 'raz' , gen_salt ( 'bf' )));
INSERT INTO users ( username , password ) VALUES ( 'raze' , crypt ( 'raze' , gen_salt ( 'bf' )));
INSERT INTO messages ( message , userid ) VALUES ( 'Test1' , ( SELECT id FROM users WHERE username = 'chelsea' ));
INSERT INTO messages ( message , userid ) VALUES ( 'Test2' , ( SELECT id FROM users WHERE username = 'chelsea' ));
INSERT INTO messages ( message , userid ) VALUES ( 'Test3' , ( SELECT id FROM users WHERE username = 'raze' ));
INSERT INTO messages ( message , userid ) VALUES ( 'Test4' , ( SELECT id FROM users WHERE username = 'raz' ));
Javascript File
#controller.js
function login ( showhide ){
if ( showhide == "show" ){
document . getElementById ( 'popupbox' ). style . visibility = "visible" ;
document . getElementById ( 'sendbox' ). style . visibility = "hidden" ;
document . getElementById ( 'searchbox' ). style . visibility = "hidden" ;
} else if ( showhide == "hide" ){
document . getElementById ( 'popupbox' ). style . visibility = "hidden" ;
document . getElementById ( 'sendbox' ). style . visibility = "visible" ;
document . getElementById ( 'searchbox' ). style . visibility = "visible" ;
}
}
var ISSChatApp = angular . module ( 'ISSChatApp' , []);
ISSChatApp . controller ( 'ChatController' , function ( $scope ){
var socket = io . connect ( 'https://' + document . domain + ':' + location . port + '/iss' );
$scope . messages = [];
$scope . found = [];
$scope . name = '' ;
$scope . text = '' ;
socket . on ( 'connect' , function (){
console . log ( 'connected' );
});
$scope . login2 = function login2 () {
console . log ( "Trying to log in" );
socket . emit ( 'login' , $scope . name2 , $scope . password );
};
socket . on ( 'loggedin' , function ( username ){
console . log ( 'login hidden' );
login ( 'hide' );
$scope . name = username ;
$scope . $apply ();
});
$scope . setName = function setName () {
console . log ( 'setting name' );
$scope . name = $scope . name2 ;
};
$scope . send2 = function send2 (){
console . log ( 'Sending message: ' , $scope . text );
socket . emit ( 'message' , $scope . text );
$scope . text = '' ;
};
socket . on ( 'message' , function ( msg ){
console . log ( 'messaging' );
$scope . messages . push ( msg );
$scope . $apply ();
var elem = document . getElementById ( 'msgpane' );
elem . scrollTop = elem . scrollHeight ;
});
$scope . searching = function searching () {
console . log ( "Searching for " + $scope . term );
socket . emit ( 'search' , $scope . term );
};
socket . on ( 'found' , function ( msg ){
console . log ( 'print results' );
$scope . found . push ( msg );
$scope . $apply ();
var elem = document . getElementById ( 'msgpane2' );
elem . scrollTop = elem . scrollHeight ;
});
socket . on ( 'clear' , function (){
console . log ( 'clear' );
$scope . found = [];
$scope . $apply ();
});
});