1.概述
WebSocket準確的講是對現有的Http協議的擴展和補充,相比於使用長輪詢和ajax輪詢來說,使用WebSocket可以獲得更加高效地實時遠程通信。
使用WebSocket可以使用第三方框架,如Netty等,也可以使用Tomcat7以上版本自帶的WebSocket支持功能。
使用WebSocket可以解決Web開發中經常遇到的跨域問題。
2.使用方法
(1)使用Tomcat 7方式:
html部分:
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<button onclick="start()">測試</button>
<div id="messages"></div>
<script type="text/JavaScript">
var webSocket = null;
function init()
{
webSocket = new WebSocket('ws://127.0.0.1:8082/WebSocketAndTomcat/java/socket'); //建立連接點 WebSocketAndTomcat要換成自己的項目名
webSocket.onerror = function(event)
{
onError(event);
};
webSocket.onopen = function(event)
{
onOpen(event);
};
webSocket.onmessage = function(event) //接受客戶端消息
{
onMessage(event);
};
}
function onMessage(event)
{
document.getElementById('messages').innerHTML += '<br />' + event.data;
}
function onOpen(event)
{
document.getElementById('messages').innerHTML = 'Connection established';
webSocket.send("ds"); //發送消息給服務器端
}
function onError(event)
{
alert(event.data);
}
function start()
{
init();
}
</script>
</body>
</html>
服務端:
package websocket;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
public class HelloWebSocketServlet extends WebSocketServlet {
private static final long serialVersionUID = 1L;
private final AtomicInteger connectionIds = new AtomicInteger(0);
@Override
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest request) {
return new HelloMessageInbound(connectionIds.getAndIncrement(), request
.getSession().getId());
}
}
(2)使用Tomcat 8方式:
html部分:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>websocket1.html</title>
<script type="text/javascript">
var wsuri = "ws://localhost:8080/Websocket1Action";
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket(wsuri);
else if ('MozWebSocket' in window)
ws = new MozWebSocket(wsuri);
else
alert("not support");
ws.onmessage = function(evt) {
alert(evt.data);
};
ws.onclose = function(evt) {
alert("close");
};
ws.onopen = function(evt) {
alert("open");
};
}
function sendMsg() {
ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"/>
<input type="button" value="send" onclick="sendMsg()"/>
</body>
</html>
服務端(使用Endpoint 方式):
package org.sl.action;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Created by shanl on 14-3-2.
*/
//@ServerEndpoint(value = "/Websocket1Action")
public class Websocket1Action extends Endpoint {
private Session session;
//private static final Logger sysLogger = Logger.getLogger("sysLog");
@Override
public void onClose(Session session, CloseReason closeReason) {
System.out.println("onClose");
}
@Override
public void onError(Session session, java.lang.Throwable throwable) {
System.out.println("onError");
}
@Override
public void onOpen(Session session, EndpointConfig config) {
//sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId());
RemoteEndpoint.Basic remote = session.getBasicRemote();
System.out.println("pathParams:"+session.getPathParameters());
System.out.println("requestParams"+session.getRequestParameterMap());
session.addMessageHandler(new MyMessageHandle(remote));
/***
try{
System.out.println("onOpen");
//System.out.println(session.getQueryString());
System.out.println(session.getRequestParameterMap());
session.getBasicRemote().getSendWriter().write("success");
//session.getBasicRemote().sendText("success");
}catch(Exception ex){
ex.printStackTrace();
}
***/
}
private class MyMessageHandle implements MessageHandler.Whole<String> {
RemoteEndpoint.Basic remote = null;
public MyMessageHandle(RemoteEndpoint.Basic remote){
this.remote = remote;
}
@Override
public void onMessage(String s) {
try {
remote.sendText("success");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
html部分:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>websocket2.html</title>
<script type="text/javascript">
var wsuri = "ws://localhost:8080/Websocket2/";
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket(wsuri);
else if ('MozWebSocket' in window)
ws = new MozWebSocket(wsuri);
else
alert("not support");
ws.onmessage = function(evt) {
alert(evt.data);
};
ws.onclose = function(evt) {
alert("close");
};
ws.onopen = function(evt) {
alert("open");
};
}
function sendMsg() {
ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"/>
<input type="button" value="send" onclick="sendMsg()"/>
</body>
</html>
服務端(使用註解方式):
package org.sl.action;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Created by shanl on 14-3-2.
*/
@ServerEndpoint(value = "/Websocket2")
public class Websocket2Action {
private Session session;
//private static final Logger sysLogger = Logger.getLogger("sysLog");
@OnOpen
public void open(Session session,EndpointConfig config) {
this.session = session;
//sysLogger.info("*** WebSocket opened from sessionId " + session.getId());
}
@OnMessage
public void inMessage(Session session,String message) {
//sysLogger.info("*** WebSocket Received from sessionId " + this.session.getId() + ": " + message);
System.out.println("rece:"+message);
try {
session.getBasicRemote().sendText("success");
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void end(Session session) {
//sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId());
}
}
(3)使用第三方框架:
可選的第三方框架較多,這裏主要以Netty爲例。
(未完待續...)