最近一直在思考一个问题:服务器如何主动发消息给浏览器?传统的Web都是浏览器主动向服务器发送请求,服务器收到请求之后返回数据给浏览器。如果要实现服务器主动向浏览器发送消息,即实现Web版的即时通信应该怎么做?貌似没有答案。之前有考虑用轮询的方式实现伪即时通信,client1要发送消息给client2,只能先把消息发送给服务器,服务器等到client2来查询有没有新消息的时候才把client1发来的消息转发给client2.这样就必须在client页面定时向服务器发送查询请求,比如5秒一次或10秒一次,实现伪即时通信。
端午节放假逛51cto发现一种比较好的解决方案:Websocket,下面记录几个Java写的Websocket的栗子,真正的即时通信。
栗子1
前端如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> var wsuri = "ws://localhost:8080/Websocket/Websocket?name=shang&password=123456"; 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 > <input type="text" id="writeMsg" /> <input type="button" value="send" onclick="sendMsg()" /> </body> </html>
后端如下
package com.websocket; import java.io.IOException; import javax.websocket.CloseReason; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/Websocket") public class Websocket extends Endpoint { private Session session; @Override public void onOpen(Session session, EndpointConfig config) { RemoteEndpoint.Basic remote = session.getBasicRemote(); System.out.println("pathParams:" + session.getPathParameters()); System.out.println("requestParams" + session.getRequestParameterMap()); session.addMessageHandler(new MyMessageHandle(remote)); } @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"); } 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) { System.out.println(s); try { remote.sendText("success"); } catch (IOException e) { e.printStackTrace(); } } } }
运测试运行在Tomcat7上正常
栗子2
前端如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> var wsuri = "ws://localhost:8080/Websocket/Websocket1?name=shang&password=123456"; 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 > <input type="text" id="writeMsg" /> <input type="button" value="send" onclick="sendMsg()" /> </body> </html>
后端如下
package com.websocket; import java.io.IOException; import javax.websocket.EndpointConfig; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/Websocket1") public class Websocket1 { private Session session; @OnOpen public void open(Session session, EndpointConfig config) { this.session = session; System.out.println("*** WebSocket opened from sessionId " + session.getId()); // 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("WebSocket Received from sessionId:" + session.getId() + "-->" + message); try { session.getBasicRemote().sendText("Server收到消息:" + message); } catch (IOException e) { e.printStackTrace(); } } @OnClose public void end(Session session) { // sysLogger.info("*** WebSocket closed from sessionId " + // this.session.getId()); System.out.println("*** WebSocket closed from sessionId " + this.session.getId()); } }
测试Tomcat7
栗子3
前端如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script language="JavaScript"> var wsuri = "ws://localhost:8080/Websocket/Websocket2"; var ws = null; function connectEndpoint() { ws = new WebSocket(wsuri); ws.onmessage = function(evt) { //alert(evt.data); document.getElementById("echo").value = evt.data; }; ws.onclose = function(evt) { //alert("close"); document.getElementById("echo").value = "end"; }; ws.onopen = function(evt) { //alert("open"); document.getElementById("echo").value = "open"; }; } function sendmsg() { ws.send(document.getElementById("send").value); } </script> </head> <body > <input type="text" size="20" value="5" id="send"> <input type="button" value="send" onclick="sendmsg()"> <br> <input type="text" id="echo"> </body> </html>
后端如下
package com.websocket; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value="/Websocket2") public class Websocket2 { @OnOpen public void start(Session session){ System.out.println("session "+session.getId()+" open."); } @OnMessage public void process(Session session, String message){ System.out.println("rece:" + message); RemoteEndpoint.Basic remote = session.getBasicRemote(); int c = Integer.valueOf(message); for (int i=1; i<=c; i++){ try { remote.sendText("response "+i); Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } } @OnClose public void end(Session session){ System.out.println("session "+session.getId()+" close."); } @OnError public void error(Session session, java.lang.Throwable throwable){ System.err.println("session "+session.getId()+" error:"+throwable); } }
Layer有一款颜值很高的web聊天界面http://sentsin.com/layui/layim/
如果要实现网页在线聊天可以考虑结合layer的前端和websocket来实现...
2015年6月30日22:15:36 By:umgsai 湖北宜昌
时间: 2024-09-29 11:34:55