tomcat8真正支持jsr-356(包含对websocket的支持), tomcat7部分版本的websocket实现不兼容jsr-356。
需要注意websocket与浏览器的兼容问题,有些早期版本的浏览器支持旧版本的websocket协议,可能会与新版本的websocket不兼容。 博主采用"chrome 版本 33.0.1750.117 m"测试。
据称websocket还会有变动,甚至可能从html5中独立出来,所以不保证当前代码在未来也能执行。
由于博主所用的eclipse不支持tomcat8,所以采用idea 13 开发(tomcat8.0.3+jdk7+servlet 3.0)。
Endpoint的session,并不是servlet的session,Endpoint的session更象是独立的记数,Endpoint如何使用servlet的session还在测试。
参考文档:
http://wenku.baidu.com/view/4e3d2d34915f804d2a16c119.html
http://tools.ietf.org/html/rfc6455
http://www.infoq.com/cn/news/2013/07/ee7-websocket-support
1package org.sl.action; 2 3//import org.apache.log4j.Logger; 4 5import javax.websocket.*; 6import javax.websocket.server.ServerEndpoint; 7import java.io.IOException; 8import java.util.*; 9 10/** 11 * Created by shanl on 14-4-14. 12 */ 13@ServerEndpoint(value="/chatendpoint") 14public class ChatEndpoint { 15 //static final Logger logger = Logger.getLogger(ChatEndpoint.class); 16 static Map<String,Session> sessionMap = new Hashtable<String,Session>(); 17 18 @OnOpen 19 public void start(Session session){ 20 System.out.println("Guest"+session.getId()+" join"); 21 sessionMap.put(session.getId(), session); 22 broadcast("Guest" + session.getId() + " join."); 23 } 24 25 @OnMessage 26 public void process(Session session, String message){ 27 System.out.println(session.getId()+" say: " + message); 28 broadcast("Guest"+session.getId()+" [say]: "+message); 29 } 30 31 32 @OnClose 33 public void end(Session session){ 34 System.out.println("Guest"+session.getId()+" out."); 35 sessionMap.remove(session.getId()); 36 broadcast("Guest"+session.getId()+ " out."); 37 } 38 39 @OnError 40 public void error(Session session, java.lang.Throwable throwable){ 41 System.err.println("Guest" + session.getId() + " error: " + throwable); 42 end(session); 43 } 44 45 void broadcast(String message){ 46 RemoteEndpoint.Basic remote = null; 47 Set<Map.Entry<String,Session>> set = sessionMap.entrySet(); 48 for(Map.Entry<String,Session> i: set){ 49 remote = i.getValue().getBasicRemote(); 50 try { 51 remote.sendText(message); 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 } 56 } 57 58} 59 60package org.sl.action; 61 62import org.omg.CosNaming._NamingContextExtStub; 63 64import javax.websocket.*; 65import javax.websocket.server.ServerEndpoint; 66 67/** 68 * Created by shanl on 14-3-3. 69 */ 70@ServerEndpoint(value="/echoendpoint") 71public class EchoEndpoint { 72 @OnOpen 73 public void start(Session session){ 74 System.out.println("session "+session.getId()+" open."); 75 } 76 77 @OnMessage 78 public void process(Session session, String message){ 79 System.out.println("rece:" + message); 80 RemoteEndpoint.Basic remote = session.getBasicRemote(); 81 int c = Integer.valueOf(message); 82 for (int i=1; i<=c; i++){ 83 try { 84 remote.sendText("response "+i); 85 Thread.sleep(500); 86 } catch (Exception e) { 87 e.printStackTrace(); 88 } 89 } 90 } 91 92 @OnClose 93 public void end(Session session){ 94 System.out.println("session "+session.getId()+" close."); 95 } 96 97 @OnError 98 public void error(Session session, java.lang.Throwable throwable){ 99 System.err.println("session "+session.getId()+" error:"+throwable); 100 } 101} 102 103package org.sl.action; 104 105import javax.servlet.ServletConfig; 106import javax.servlet.ServletException; 107import javax.servlet.annotation.WebInitParam; 108import javax.servlet.annotation.WebServlet; 109import javax.servlet.http.HttpServlet; 110import javax.servlet.http.HttpServletRequest; 111import javax.servlet.http.HttpServletResponse; 112import javax.servlet.http.HttpSession; 113import java.io.IOException; 114import java.io.PrintWriter; 115 116/** 117 * Created by shanl on 14-3-2. 118 */ 119@WebServlet(name="HelloAction" ,urlPatterns={"/HelloAction"},loadOnStartup=1, 120 initParams={ 121 @WebInitParam(name="name",value="xiazdong"), 122 @WebInitParam(name="age",value="20") 123}) 124public class HelloAction extends HttpServlet { 125 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 126 ServletConfig config = getServletConfig(); 127 HttpSession session = request.getSession(); 128 PrintWriter out = response.getWriter(); 129 out.println("<html>"); 130 out.println("<body>"); 131 out.println("Hello world"+"<br />"); 132 out.println("name :"+config.getInitParameter("name")+"<br/>"); 133 out.println("session id :"+session.getId()); 134 out.println("</body>"); 135 out.println("</html>"); 136 out.close(); 137 } 138} 139 140package org.sl.action; 141 142import javax.websocket.*; 143import javax.websocket.server.ServerEndpoint; 144import java.io.IOException; 145 146/** 147 * Created by shanl on 14-3-2. 148 */ 149//@ServerEndpoint(value = "/Websocket1Action") 150public class Websocket1Action extends Endpoint { 151 private Session session; 152 //private static final Logger sysLogger = Logger.getLogger("sysLog"); 153 @Override 154 public void onClose(Session session, CloseReason closeReason) { 155 System.out.println("onClose"); 156 } 157 158 @Override 159 public void onError(Session session, java.lang.Throwable throwable) { 160 System.out.println("onError"); 161 } 162 163 @Override 164 public void onOpen(Session session, EndpointConfig config) { 165 //sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId()); 166 RemoteEndpoint.Basic remote = session.getBasicRemote(); 167 168 System.out.println("pathParams:"+session.getPathParameters()); 169 System.out.println("requestParams"+session.getRequestParameterMap()); 170 session.addMessageHandler(new MyMessageHandle(remote)); 171 /*** 172 try{ 173 System.out.println("onOpen"); 174 //System.out.println(session.getQueryString()); 175 System.out.println(session.getRequestParameterMap()); 176 session.getBasicRemote().getSendWriter().write("success"); 177 //session.getBasicRemote().sendText("success"); 178 }catch(Exception ex){ 179 ex.printStackTrace(); 180 } 181 ***/ 182 } 183 184 private class MyMessageHandle implements MessageHandler.Whole<String> { 185 RemoteEndpoint.Basic remote = null; 186 public MyMessageHandle(RemoteEndpoint.Basic remote){ 187 this.remote = remote; 188 } 189 190 @Override 191 public void onMessage(String s) { 192 try { 193 remote.sendText("success"); 194 } catch (IOException e) { 195 e.printStackTrace(); 196 } 197 } 198 } 199} 200 201package org.sl.action; 202 203import javax.websocket.*; 204import javax.websocket.server.ServerEndpoint; 205import java.io.IOException; 206 207/** 208 * Created by shanl on 14-3-2. 209 */ 210@ServerEndpoint(value = "/Websocket2") 211public class Websocket2Action { 212 private Session session; 213 //private static final Logger sysLogger = Logger.getLogger("sysLog"); 214 215 @OnOpen 216 public void open(Session session,EndpointConfig config) { 217 this.session = session; 218 219 //sysLogger.info("*** WebSocket opened from sessionId " + session.getId()); 220 } 221 222 @OnMessage 223 public void inMessage(Session session,String message) { 224 //sysLogger.info("*** WebSocket Received from sessionId " + this.session.getId() + ": " + message); 225 System.out.println("rece:"+message); 226 try { 227 session.getBasicRemote().sendText("success"); 228 } catch (IOException e) { 229 e.printStackTrace(); 230 } 231 } 232 233 @OnClose 234 public void end(Session session) { 235 //sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId()); 236 } 237 238} 239 240<!DOCTYPE html> 241<html> 242<head> 243 <title>echoendpoint.html</title> 244 <script language="JavaScript"> 245 var wsuri = "ws://localhost:8080/echoendpoint"; 246 var ws = null; 247 248 function connectEndpoint(){ 249 ws = new WebSocket(wsuri); 250 ws.onmessage = function(evt) { 251 //alert(evt.data); 252 document.getElementById("echo").value = evt.data; 253 }; 254 255 ws.onclose = function(evt) { 256 //alert("close"); 257 document.getElementById("echo").value = "end"; 258 }; 259 260 ws.onopen = function(evt) { 261 //alert("open"); 262 document.getElementById("echo").value = "open"; 263 }; 264 } 265 266 function sendmsg(){ 267 ws.send(document.getElementById("send").value); 268 } 269 </script> 270</head> 271<body onload="connectEndpoint()"> 272 <input type="text" size="20" value="5" id="send"> <input type="button" value="send" onclick="sendmsg()"> <br> 273 <input type="text" id="echo"> 274</body> 275</html> 276 277<!DOCTYPE html> 278<html> 279<head> 280 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 281 <title>websocket1.html</title> 282 <script type="text/javascript"> 283 var wsuri = "ws://localhost:8080/Websocket1Action"; 284 var ws = null; 285 function startWebSocket() { 286 if ('WebSocket' in window) 287 ws = new WebSocket(wsuri); 288 else if ('MozWebSocket' in window) 289 ws = new MozWebSocket(wsuri); 290 else 291 alert("not support"); 292 293 294 ws.onmessage = function(evt) { 295 alert(evt.data); 296 }; 297 298 ws.onclose = function(evt) { 299 alert("close"); 300 }; 301 302 ws.onopen = function(evt) { 303 alert("open"); 304 }; 305 } 306 307 function sendMsg() { 308 ws.send(document.getElementById('writeMsg').value); 309 } 310 </script> 311</head> 312<body onload="startWebSocket();"> 313<input type="text" id="writeMsg"/> 314<input type="button" value="send" onclick="sendMsg()"/> 315</body> 316</html> 317 318<!DOCTYPE html> 319<html> 320<head> 321 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 322 <title>websocket2.html</title> 323 <script type="text/javascript"> 324 var wsuri = "ws://localhost:8080/Websocket2/"; 325 var ws = null; 326 function startWebSocket() { 327 if ('WebSocket' in window) 328 ws = new WebSocket(wsuri); 329 else if ('MozWebSocket' in window) 330 ws = new MozWebSocket(wsuri); 331 else 332 alert("not support"); 333 334 335 ws.onmessage = function(evt) { 336 alert(evt.data); 337 }; 338 339 ws.onclose = function(evt) { 340 alert("close"); 341 }; 342 343 ws.onopen = function(evt) { 344 alert("open"); 345 }; 346 } 347 348 function sendMsg() { 349 ws.send(document.getElementById('writeMsg').value); 350 } 351 </script> 352</head> 353<body onload="startWebSocket();"> 354<input type="text" id="writeMsg"/> 355<input type="button" value="send" onclick="sendMsg()"/> 356</body> 357</html> 358 359<%-- Created by IntelliJ IDEA. --%> 360<%@ page contentType="text/html;charset=UTF-8" language="java" %> 361<html> 362 <head> 363 <title>index.jsp</title> 364 </head> 365 <body> 366 index.jsp<br/> 367 <a href="https://my.oschina.net/HelloAction">HelloAction</a> <br> 368 <a href="https://my.oschina.net/WebsocketAction">WebsocketAction</a> <br> 369 <a href="websocket1.html">websocket1.html</a> <br> 370 <a href="websocket2.html">websocket2.html</a> <br> 371 <a href="echoendpoint.html">echoendpoint.html</a> <br> 372 373 </body> 374</html> 375 376<!DOCTYPE html> 377<html> 378<head> 379 <title>chatendpoint.html</title> 380 <script language="JavaScript"> 381 var wsuri = "ws://localhost:8080/chatendpoint"; 382 var ws = null; 383 384 function connectEndpoint(){ 385 window.WebSocket = window.WebSocket || window.MozWebSocket; 386 if (!window.WebSocket){ 387 alert("WebSocket not supported by this browser"); 388 return; 389 } 390 391 ws = new WebSocket(wsuri); 392 ws.onmessage = function(evt) { 393 //alert(evt.data); 394 var old = document.getElementById("echo").value; 395 document.getElementById("echo").value = old+evt.data+"\r\n"; 396 }; 397 398 ws.onclose = function(evt) { 399 //alert("close"); 400 document.getElementById("echo").value = "server disconnect.\r\n"; 401 }; 402 403 ws.onopen = function(evt) { 404 //alert("open"); 405 document.getElementById("echo").value = "connect server.\r\n"; 406 }; 407 } 408 409 function sendmsg(){ 410 ws.send(document.getElementById("send").value); 411 } 412 </script> 413</head> 414<body onload="connectEndpoint()"> 415<input type="text" size="20" value="hi~" id="send"> <input type="button" value="send" onclick="sendmsg()"> <br> 416<textarea id="echo" rows="50" cols="50"> 417</textarea> 418</body> 419</html>