IM Framework based on WebSocket - SparkJava and NodeJs

Node.js and WebSocket


var app = require('express')();
var http = require('http').Server(app);
var io = require('')(http);

app.get('/', function(req, res){
	res.send('<h1>Welcome Realtime Server</h1>');

var onlineUsers = {};
var onlineCount = 0;

io.on('connection', function(socket){
	console.log('a user connected');
	socket.on('login', function(obj){
		//将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到 = obj.userid;
		if(!onlineUsers.hasOwnProperty(obj.userid)) {
			onlineUsers[obj.userid] = obj.username;
		io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
	socket.on('disconnect', function(){
		if(onlineUsers.hasOwnProperty( {
			var obj = {, username:onlineUsers[]};
			delete onlineUsers[];
			io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
	socket.on('message', function(obj){
		io.emit('message', obj);

http.listen(3000, function(){
	console.log('listening on *:3000');


<!DOCTYPE html>
        <meta charset="utf-8">
        <meta name="format-detection" content="telephone=no"/>
        <meta name="format-detection" content="email=no"/>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" name="viewport">
        <link rel="stylesheet" type="text/css" href="./style.css" />
        <!--[if lt IE 8]><script src="./json3.min.js"></script><![endif]-->
        <script src=""></script>
        <div id="loginbox">
            <div style="width:260px;margin:200px auto;">
                <input type="text" style="width:180px;" placeholder="请输入用户名" id="username" name="username" />
				<input type="button" style="width:50px;" value="提交" onclick="CHAT.usernameSubmit();"/>
        <div id="chatbox" style="display:none;">
            <div style="background:#3d3d3d;height: 28px; width: 100%;font-size:12px;">
                <div style="line-height: 28px;color:#fff;">
                    <span style="text-align:left;margin-left:10px;">Websocket多人聊天室</span>
                    <span style="float:right; margin-right:10px;"><span id="showusername"></span> | 
					<a href="javascript:;" onclick="CHAT.logout()" style="color:#fff;">退出</a></span>
            <div id="doc">
                <div id="chat">
                    <div id="message" class="message">
<div id="onlinecount" style="background:#EFEFF4; font-size:12px; margin-top:10px; margin-left:10px; color:#666;">
                    <div class="input-box">
                        <div class="input">
<input type="text" maxlength="140" placeholder="请输入聊天内容,按Ctrl提交" id="content" name="content">
                        <div class="action">
                            <button type="button" id="mjr_send" onclick="CHAT.submit();">提交</button>
                        <div style="font-size: 12px;float:left;position: absolute;width:100%;top:45px;left:10px">
						<p>如果这个Demo对你有帮助,<a href="" target="_blank">请到Github关注我</a></p>
						<p>教程:<a href="" target="_blank"></a></p>
                        	<p>源码:<a href="" target="_blank"></a></p>
        <script type="text/javascript" src="./client.js"></script>


(function () {
	var d = document,
	w = window,
	p = parseInt,
	dd = d.documentElement,
	db = d.body,
	dc = d.compatMode == 'CSS1Compat',
	dx = dc ? dd: db,
	ec = encodeURIComponent;
	w.CHAT = {
		screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
			w.scrollTo(0, this.msgObj.clientHeight);
			var content = d.getElementById("content").value;
			if(content != ''){
				var obj = {
					userid: this.userid,
					username: this.username,
					content: content
				this.socket.emit('message', obj);
				d.getElementById("content").value = '';
			return false;
			return new Date().getTime()+""+Math.floor(Math.random()*899+100);
		updateSysMsg:function(o, action){
			var onlineUsers = o.onlineUsers;
			var onlineCount = o.onlineCount;
			var user = o.user;
			var userhtml = '';
			var separator = '';
			for(key in onlineUsers) {
					userhtml += separator+onlineUsers[key];
					separator = '、';
			d.getElementById("onlinecount").innerHTML = '当前共有 '+onlineCount+' 人在线,在线列表:'+userhtml;
			var html = '';
			html += '<div class="msg-system">';
			html += user.username;
			html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';
			html += '</div>';
			var section = d.createElement('section');
			section.className = 'system J-mjrlinkWrap J-cutMsg';
			section.innerHTML = html;
			var username = d.getElementById("username").value;
			if(username != ""){
				d.getElementById("username").value = '';
				d.getElementById("loginbox").style.display = 'none';
				d.getElementById("chatbox").style.display = 'block';
			return false;
			this.userid = this.genUid();
			this.username = username;
			d.getElementById("showusername").innerHTML = this.username;
			// = (this.screenheight - db.clientHeight + this.msgObj.clientHeight) + "px";
			this.socket = io.connect('ws://');
			this.socket.emit('login', {userid:this.userid, username:this.username});
			this.socket.on('login', function(o){
				CHAT.updateSysMsg(o, 'login');	
			this.socket.on('logout', function(o){
				CHAT.updateSysMsg(o, 'logout');
			this.socket.on('message', function(obj){
				var isme = (obj.userid == CHAT.userid) ? true : false;
				var contentDiv = '<div>'+obj.content+'</div>';
				var usernameDiv = '<span>'+obj.username+'</span>';
				var section = d.createElement('section');
					section.className = 'user';
					section.innerHTML = contentDiv + usernameDiv;
				} else {
					section.className = 'service';
					section.innerHTML = usernameDiv + contentDiv;

	d.getElementById("username").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {
	d.getElementById("content").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {

Run and browse:


Video streaming over websockets using JavaScript

What is the fastest way to stream live video using JavaScript? Is WebSockets over TCP a fast enough protocol to stream a video of, say, 30fps?

Yes.. it is, take a look at this project. Websockets can easily handle HD videostreaming.. However, you should go for Adaptive Streaming. I explain here how you could implement it.

Currently we’re working on a webbased instant messaging application with chat, filesharing and video/webcam support. With some bits and tricks we got streaming media through websockets (used HTML5 Media Capture to get the stream from our webcams).

You need to build a stream API and a Media Stream Transceiver to control the related media processing and transport.

Video streaming over websockets using JavaScript

How do we split our audio/video data in chunks with Python?

We are currently working on a chat + (file sharing +) video conference application using HTML5 websockets. To make our application more accessible we want to implement Adaptive Streaming, using the following sequence:

  • Raw audio/video data client goes to server
  • Stream is split into 1 second chunks
  • Encode stream into varying bandwidths
  • Client receives manifest file describing available segments
  • Downloads one segment using normal HTTP
  • Bandwidth next segment chosen on performance of previous one
  • Client may select from a number of different alternate streams at a variety of data rates

So.. How do we split our audio/video data in chunks with Python?

Chopping media stream in HTML5 websocket server for webbased chat/video conference application

Spark and WebSocket


public class Chat {

    static Map<Session, String> userUsernameMap = new HashMap<>();
    static int nextUserNumber = 1; //Assign to username for next connecting user

    public static void main(String[] args) {
        staticFileLocation("public"); //index.html is served at localhost:4567 (default port)
        webSocket("/chat", ChatWebSocketHandler.class);

    //Sends a message from one user to all users, along with a list of current usernames
    public static void broadcastMessage(String sender, String message) {
        userUsernameMap.keySet().stream().filter(Session::isOpen).forEach(session -> {
            try {
                session.getRemote().sendString(String.valueOf(new JSONObject()
                    .put("userMessage", createHtmlMessageFromSender(sender, message))
                    .put("userlist", userUsernameMap.values())
            } catch (Exception e) {

    //Builds a HTML element with a sender-name, a message, and a timestamp,
    private static String createHtmlMessageFromSender(String sender, String message) {
        return article().with(
                b(sender + " says:"),
                span().withClass("timestamp").withText(new SimpleDateFormat("HH:mm:ss").format(new Date()))



public class ChatWebSocketHandler {

	private String sender, msg;

	public void onConnect(Session user) throws Exception {
		String username = "User" + Chat.nextUserNumber++;
		Chat.userUsernameMap.put(user, username);
		Chat.broadcastMessage(sender = "Server", msg = (username + " joined the chat"));

	public void onClose(Session user, int statusCode, String reason) {
		String username = Chat.userUsernameMap.get(user);
		Chat.broadcastMessage(sender = "Server", msg = (username + " left the chat"));

	public void onMessage(Session user, String message) {
		Chat.broadcastMessage(sender = Chat.userUsernameMap.get(user), msg = message);


<!DOCTYPE html>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css">
    <div id="chatControls">
        <input id="message" placeholder="Type your message">
        <button id="send">Send</button>
    <ul id="userlist"> <!-- Built by JS --> </ul>
    <div id="chat">    <!-- Built by JS --> </div>
    <script src="websocketDemo.js"></script>


//Establish the WebSocket connection and set up event handlers
var webSocket = new WebSocket("ws://" + location.hostname + ":" + location.port + "/chat/");
webSocket.onmessage = function (msg) { updateChat(msg); };
webSocket.onclose = function () { alert("WebSocket connection closed") };

//Send message if "Send" is clicked
id("send").addEventListener("click", function () {

//Send message if enter is pressed in the input field
id("message").addEventListener("keypress", function (e) {
    if (e.keyCode === 13) { sendMessage(; }

//Send a message if it's not empty, then clear the input field
function sendMessage(message) {
    if (message !== "") {
        id("message").value = "";

//Update the chat-panel, and the list of connected users
function updateChat(msg) {
    var data = JSON.parse(;
    insert("chat", data.userMessage);
    id("userlist").innerHTML = "";
    data.userlist.forEach(function (user) {
        insert("userlist", "<li>" + user + "</li>");

//Helper function for inserting HTML as the first child of an element
function insert(targetId, message) {
    id(targetId).insertAdjacentHTML("afterbegin", message);

//Helper function for selecting element by id
function id(id) {
    return document.getElementById(id);

Run and browse:


How to stream audio/video data over websocket using javascript?

Use java-ffmpeg wrapper, or simply use java runtime to execute ffmpeg?

todo…problem to solve

Written on March 29, 2016