基于html5 WebSocket和WebRTC实现IM和视音频呼叫(二)

在上篇文( 基于html5 WebSocket和WebRTC实现IM和视音频呼叫(一))里我们已经用Jetty-7.5.4.v20111024搭起了一个WebSocket server,现在就可以编写自己的WebSocket Server逻辑完成自己的实现了。

一、编写WebSocket服务端逻辑

MyWebSocketServlet类继承自Jetty开发包中的org.eclipse.jetty.websocket.WebSocketServlet类,用于实现我们的WebSocket 服务端入口。前期没有编写太多的服务端逻辑,只是实现了接受并记录所有连接client端,并广播所有client端消息的功能,代码如下:

MyWebSocketServlet.javapackage com.webrtcserver;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;

public class MyWebSocketServlet extends WebSocketServlet {
	private static final long serialVersionUID = -7289719281366784056L;
	public static String newLine = System.getProperty("line.separator");

	private final Set _members = new CopyOnWriteArraySet();

	public void init() throws ServletException {
		super.init();

	}

	private void broadcastMessage(String msg) {
		for (TailorSocket member : _members) {
			logs("Trying to send to Member!");
			if (member.isOpen()) {
				logs("Sending!");
				try {
					member.sendMessage(msg);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		getServletContext().getNamedDispatcher("default").forward(request,
				response);
		logs("doGet");
	}

	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String protocol) {
		return new TailorSocket();
	}
	static private int serialNum = 0;
	class TailorSocket implements WebSocket.OnTextMessage {
		private Connection _connection;
		private String sdp;
		private String userName;

		public void onClose(int closeCode, String message) {
			_members.remove(this);
		}

		public void sendMessage(String data) throws IOException {
			_connection.sendMessage(data);
		}

		public void onMessage(String data) {
			logs("Received: " + data);
			broadcastMessage(data);
		}

		public boolean isOpen() {
			return _connection.isOpen();
		}

		public void onOpen(Connection connection) {
			userName = String.format("%5d", serialNum++);
			_members.add(this);
			_connection = connection;
			logs("one memner connected!");
			try {
				connection
						.sendMessage("onOpen:Server received Web Socket upgrade and added it to Receiver List.");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void logs(String logMessage) {
		System.out.println(logMessage);
	}
}

 

TailorSocket 继承自 WebSocket.OnTextMessage,每当一个client连接时就会调用doWebSocketConnect方法实例化一个client对象。

server端通过TailorSocket的_connection.sendMessage(data)方法向client发送文本消息;通过onMessage接收client发送的文本消息,并调用broadcastMessage方法向所有连接的client广播消息。

 

二、编写Client逻辑

WebSocket对象在不同的浏览器实现稍有区别,为了代码适应更多的浏览器在调用WebSocket对象前需要判断当前的浏览器,然后实现WebSocket的onopen,onmessage,onclose等方法,即可与WebSocket服务端建立连接,具体代码如下:

var server = {
	connect : function() {
		var location = get_appropriate_ws_url() + "/servlet/a";
		if (BrowserDetect.browser == "Firefox") {
			this._ws = new MozWebSocket(location, null);
		} else {
			this._ws = new WebSocket(location, null);
		}
		this._ws.onopen = this._onopen;
		this._ws.onmessage = this._onmessage;
		this._ws.onclose = this._onclose;
		showLog("connecting...");
	},

	_onopen : function() {
		showLog("connected to server!");
	},

	_send : function(message) {
		if (this._ws)
			this._ws.send(message);
	},

	send : function(text) {
		if (text != null && text.length > 0) {
			server._send(text);
		}
	},

	_onmessage : function(m) {
		if (m.data) {
			showMessage("others", m.data);
		}
		showLog("onmessage");
	},

	_onclose : function(m) {
		this._ws = null;
		showLog("onclose");
	}
};

下面的test.html和test.js简单实现了群聊聊天室:

test.html<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset = "utf-8"/>
        <title>WebRTC && Web Sockets Demotitle>
        <script type="text/javascript" src="JS/test.js">script>
        <style type='text/css'>
            div {
                border: 0px solid black;
            }

            div#messageBox {
                clear: both;
                width: 40em;
                height: 20ex;
                overflow: auto;
                background-color: #f0f0f0;
                padding: 4px;
                border: 1px solid black;
            }
            
            div#logBox {
                clear: both;
                width: 40em;
                height: 20ex;
                overflow: auto;
                background-color: #f0f0f0;
                padding: 4px;
                border: 1px solid black;
            }

            div#input {
                clear: both;
                width: 40em;
                padding: 4px;
                background-color: #e0e0e0;
                border: 1px solid black;
                border-top: 0px
            }

            div.hidden {
                display: none;
            }

            span.alert {
                font-style: italic;
            }
        style>
    head>
    <body>
        <div>
           <input id='connect' class='button' type='submit' name='Connect'  value='Connect' />
        div>
        <div id='messageBox'>div>
        <div id='inputButton'>
            <input id="inputBox" type="text"/>
            <input id="inputButton" type="button" value="SEND"/>
        div>
        <div id='logBox'>div>
        <script type='text/javascript'>
            $('connect').onclick =function(event) {
                server.connect();
                return false;
            };
            $("inputButton").onclick = function(event) {
                if($("inputBox").value != "") {
                    server.send($("inputBox").value);
                    $("inputBox").value = "";
                    showMessage("me", text);
                }
                return false;
            }
        script>
     body>
html>
test.jsif (!window.WebSocket)
	alert("window.WebSocket unsuport!");

function $() {
	return document.getElementById(arguments[0]);
}
function $F() {
	return document.getElementById(arguments[0]).value;
}

function getKeyCode(ev) {
	if (window.event)
		return window.event.keyCode;
	return ev.keyCode;
}

function showMessage(from, content) {
	var messageBox = $('messageBox');
	var spanText = document.createElement('span');
	spanText.className = 'text';
	spanText.innerHTML = from + ":" + content;
	var lineBreak = document.createElement('br');
	messageBox.appendChild(spanText);
	messageBox.appendChild(lineBreak);
	messageBox.scrollTop = messageBox.scrollHeight - messageBox.clientHeight;
}

function showLog(log) {
	var logBox = $("logBox");
	logBox.innerHTML = log + "
" + logBox.innerHTML
; } function get_appropriate_ws_url() { var pcol; var u = document.URL; if (u.substring(0, 5) == "https") { pcol = "wss://"; u = u.substr(8); } else { pcol = "ws://"; if (u.substring(0, 4) == "http") u = u.substr(7); } u = u.split('/'); return pcol + u[0]; } var server = { connect : function() { var location = get_appropriate_ws_url() + "/servlet/a"; if (BrowserDetect.browser == "Firefox") { this._ws = new MozWebSocket(location, "dumb-increment-protocol"); } else { this._ws = new WebSocket(location, "dumb-increment-protocol"); } this._ws.onopen = this._onopen; this._ws.onmessage = this._onmessage; this._ws.onclose = this._onclose; showLog("connecting..."); }, _onopen : function() { showLog("connected to server!"); }, _send : function(message) { if (this._ws) this._ws.send(message); }, send : function(text) { if (text != null && text.length > 0) { server._send(text); } }, _onmessage : function(m) { showMessage("others", m.data); showLog("onmessage"); }, _onclose : function(m) { this._ws = null; showLog("onclose"); } }; /* BrowserDetect came from http://www.quirksmode.org/js/detect.html */ var BrowserDetect = { init: function () { this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "an unknown version"; this.OS = this.searchString(this.dataOS) || "an unknown OS"; }, searchString: function (data) { for (var i=0;i<data.length;i++) { var dataString = data[i].string; var dataProp = data[i].prop; this.versionSearchString = data[i].versionSearch || data[i].identity; if (dataString) { if (dataString.indexOf(data[i].subString) != -1) return data[i].identity; } else if (dataProp) return data[i].identity; } }, searchVersion: function (dataString) { var index = dataString.indexOf(this.versionSearchString); if (index == -1) return; return parseFloat(dataString.substring(index+this.versionSearchString.length+1)); }, dataBrowser: [ { string: navigator.userAgent, subString: "Chrome", identity: "Chrome" }, { string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" }, { string: navigator.vendor, subString: "Apple", identity: "Safari", versionSearch: "Version" }, { prop: window.opera, identity: "Opera", versionSearch: "Version" }, { string: navigator.vendor, subString: "iCab", identity: "iCab" }, { string: navigator.vendor, subString: "KDE", identity: "Konqueror" }, { string: navigator.userAgent, subString: "Firefox", identity: "Firefox" }, { string: navigator.vendor, subString: "Camino", identity: "Camino" }, { // for newer Netscapes (6+) string: navigator.userAgent, subString: "Netscape", identity: "Netscape" }, { string: navigator.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE" }, { string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" }, { // for older Netscapes (4-) string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" } ], dataOS : [ { string: navigator.platform, subString: "Win", identity: "Windows" }, { string: navigator.platform, subString: "Mac", identity: "Mac" }, { string: navigator.userAgent, subString: "iPhone", identity: "iPhone/iPod" }, { string: navigator.platform, subString: "Linux", identity: "Linux" } ] }; BrowserDetect.init();

test2.html则用html5的canvas实现了电子白板的功能:

test2.html
en">

 
 Minimal Websocket test app




Drawing color:
Not initialized
background-color: #e0e0e0;">

 
相关资料:

http://git.warmcat.com/cgi-bin/cgit/libwebsockets/

http://dev.w3.org/html5/websockets/

转载于:https://www.cnblogs.com/longrenle/archive/2012/02/26/2368074.html

你可能感兴趣的:(基于html5 WebSocket和WebRTC实现IM和视音频呼叫(二))