前言 服务端推送信息方案及其实现
轮询 :就是一直循环访问服务端 服务端压力比较大 利用js的一些定时功能 隔一段时间发起一次请求
长轮询:一次请求 服务端吧请求保留 等由数据返回的时候 再返回 管理麻烦
长链接 例如用iframe 维护长链接开销较大 而且页面会显示一直在加载 不利于使用
flash socket:利用flash插件提供的socket 麻烦 需要会flash flash的缺点无法避免如安全
WebSocket: html5技术 利用提供的html5本身特性来实现socket ws或者wss协议 现阶段几乎所有的浏览器最新版都支持 除开个别奇葩版本
sse: server-sent event http协议变通实现的 通过服务端向客户端声明 接下来是要发送的是流信息 本质上就是完成一次耗时长的下载
web socket服务端推送 #####maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <dependencies> <!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api --> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> </dependencies>
#####页面代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>客户端</title> </head> <body> <div> <input type="button" id="bconnection" value="链接"> <input type="button" id="bclose" value="关闭"> <input type="button" id="bsend" value="发送"> <input type="text" id="sessionId" name="sessionId"> <input type="text" id="message" name="message"> <input type="button" onclick="sendServlet()" value="jdklsjlfs"> </div> <script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //模拟另外个客户向服务器发起推送消息服务 function sendServlet() { $.get("http://localhost:8080/ws/sendServlet?sessionId="+$("#sessionId").val()+"&message="+$("#message").val()); } //设立全局变量方便后续操作 var socket; //判断是否支持WebSocket if (typeof (WebSocket)=="undefined"){ alert("浏览器不支持websocket"); } $("#bconnection").click(function () { //实例化weosocket 制定服务器地址和端口 socket=new WebSocket("ws://localhost:8080/ws/websocket/xu"); //打开链接 socket.onopen=function () { console.log("打开weosocket端口"); socket.send("客户端发送打开链接请求成功") }; //获取消息事件 socket.onmessage=function (msg) { console.log("获取的消息"+msg.data); }; //关闭socket socket.onclose=function () { console.log("关闭socket"); }; //监听错误 socket.onerror=function () { console.log("socket发生错误"); } }); //发送消息 $("#bsend").click(function () { socket.send("客户端消息:"+location.href+new Date()); }); //手动关闭socket $("#bclose").click(function () { socket.close(); }); </script> </body> </html>
#####服务端代码 ######websocket链接类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package com.xxx.websocket; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** * Created by xianyu on 17-3-7. * websocket 服务端响应 */ @ServerEndpoint("/websocket/{user}") public class WebSocketService { private String socketUser; //记录session列表 private static Map<String ,Session> sessionMap=new HashMap<>(); public static void sendMessage(String sessionId,String message){ sessionMap.get(sessionId).getAsyncRemote().sendText("推送消息:"+message); } //打开socket链接的时候操作 @OnOpen public void onOpen(@PathParam("user")String user, Session session) throws IOException { socketUser=user; System.out.println("链接打开账户为"+user+"sessionid为"+session.getId()); sessionMap.put(session.getId(),session); session.getAsyncRemote().sendText("服务端成功接受链接;sessionId="+session.getId()); } //接受消息的时候操作 @OnMessage public String onMessage(String message) { System.out.println(socketUser+"客户的消息"+message); return socketUser+":"+message; } @OnError public void onError(Throwable t) { t.printStackTrace(); } @OnClose public void onClose(Session session, CloseReason reason) { System.out.println(String.format("session id 为%s 用户为%s closeReason%s",session.getId(),socketUser,reason)); } }
#####模拟发送服务端推送消息servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.xxx.websocket; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; /** * Created by xianyu on 17-3-7. */ public class SendServlet extends HttpServlet { private String messagePrefix="servlet:"; @Override public void init() throws ServletException { } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { WebSocketService.sendMessage(req.getParameter("sessionId"),messagePrefix+req.getParameter("message")+"||||||||||||"+new Date()); } @Override public void destroy() { super.destroy(); } }
总结 webscoket是现阶段实现服务端推送、在线聊天、等等需要使用tcp长链接的地比较合适的一个技术 现在市面上的浏览器最新版有不支持的websocket的 ws 和wss区别 相当于http和https区别一样