Spring-WebScoket
来源:互联网 发布:中国房地产未来知乎 编辑:程序博客网 时间:2024/04/27 22:04
1.Pom.xml
<dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies>
2.客户端的连接
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><% String path = request.getContextPath(); String basePath = request.getServerName() + ":" + request.getServerPort() + path + "/"; String basePath2 = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";%>http://www.w3.org/TR/html4/strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title></title><script type="text/javascript" src="<%=basePath2%>resources/jquery.js"></script><style>textarea { height: 300px; width: 100%; resize: none; outline: none;}input[type=button] { float: right; margin: 5px; width: 50px; height: 35px; border: none; color: white; font-weight: bold; outline: none;}.clear { background: red;}.send { background: green;}.clear:active { background: yellow;}.send:active { background: yellow;}.msg { width: 100%; height: 25px; outline: none;}#content { border: 1px solid gray; width: 100%; height: 400px; overflow-y: scroll;}.from { background-color: green; width: 80%; border-radius: 10px; height: 30px; line-height: 30px; margin: 5px; float: left; color: white; padding: 5px; font-size: 22px;}.to { background-color: gray; width: 80%; border-radius: 10px; height: 30px; line-height: 30px; margin: 5px; float: right; color: white; padding: 5px; font-size: 22px;}.name { color: gray; font-size: 12px;}.tmsg_text { color: white; background-color: rgb(47, 47, 47); font-size: 18px; border-radius: 5px; padding: 2px;}.fmsg_text { color: white; background-color: rgb(66, 138, 140); font-size: 18px; border-radius: 5px; padding: 2px;}.sfmsg_text { color: white; background-color: rgb(148, 16, 16); font-size: 18px; border-radius: 5px; padding: 2px;}.tmsg { clear: both; float: right; width: 80%; text-align: right;}.fmsg { clear: both; float: left; width: 80%;}</style><script> var path = '<%=basePath%>'; var uid=${uid eq null?-1:uid}; if(uid==-1){ location.href="<%=basePath2%>"; } var from=uid; var fromName='${name}'; var to=uid==1?2:1; var websocket; if ('WebSocket' in window) { websocket = new WebSocket("ws://" + path + "/ws?uid="+uid); } else if ('MozWebSocket' in window) { websocket = new MozWebSocket("ws://" + path + "/ws"+uid); } else { websocket = new SockJS("http://" + path + "/ws/sockjs"+uid); } websocket.onopen = function(event) { console.log("WebSocket:已连接"); console.log(event); }; websocket.onmessage = function(event) { var data=JSON.parse(event.data); console.log("WebSocket:收到一条消息",data); var textCss=data.from==-1?"sfmsg_text":"fmsg_text"; $("#content").append("<div class='fmsg'><label class='name'>"+data.fromName+" "+data.date+"</label><div class='"+textCss+"'>"+data.text+"</div></div>"); scrollToBottom(); }; websocket.onerror = function(event) { console.log("WebSocket:发生错误 "); console.log(event); }; websocket.onclose = function(event) { console.log("WebSocket:已关闭"); console.log(event); } function sendMsg(){ var v=$("#msg").val(); if(v==""){ return; }else{ var data={}; data["from"]=from; data["fromName"]=fromName; data["to"]=to; data["text"]=v; websocket.send(JSON.stringify(data)); $("#content").append("<div class='tmsg'><label class='name'>我 "+new Date().Format("yyyy-MM-dd hh:mm:ss")+"</label><div class='tmsg_text'>"+data.text+"</div></div>"); scrollToBottom(); $("#msg").val(""); } } function scrollToBottom(){ var div = document.getElementById('content'); div.scrollTop = div.scrollHeight; } Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } function send(event){ var code; if(window.event){ code = window.event.keyCode; // IE }else{ code = e.which; // Firefox } if(code==13){ sendMsg(); } } function clearAll(){ $("#content").empty(); } </script></head><body> 欢迎:${sessionScope.name } <div id="content"></div> <input type="text" placeholder="请输入要发送的信息" id="msg" class="msg" onkeydown="send(event)"> <input type="button" value="发送" class="send" onclick="sendMsg()" > <input type="button" value="清空" class="clear" onclick="clearAll()"></body></html>
3.编码实现
1.WebScoket配置处理器
import javax.annotation.Resource;import org.springframework.stereotype.Component;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;/** * WebScoket配置处理器 * @author Goofy * @Date 2015年6月11日 下午1:15:09 */@Component@EnableWebSocketpublic class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { @Resource MyWebSocketHandler handler; public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(handler, "/ws").addInterceptors(new HandShake()); registry.addHandler(handler, "/ws/sockjs").addInterceptors(new HandShake()).withSockJS(); }}
2.Socket建立连接(握手)和断开
import java.util.Map;import javax.servlet.http.HttpSession;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.HandshakeInterceptor;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;/** * Socket建立连接(握手)和断开 * * @author Goofy * @Date 2015年6月11日 下午2:23:09 */public class HandShake extends HttpSessionHandshakeInterceptor { public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { System.out.println("Websocket:用户[ID:" + ((ServletServerHttpRequest) request).getServletRequest().getSession(false).getAttribute("uid") + "]已经建立连接"); if (request instanceof ServletServerHttpRequest) {//instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例 ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false);//如果当前session没有就返回null // 标记用户 Long uid = (Long) session.getAttribute("uid");//登陆用户ID if(uid!=null){ attributes.put("uid", uid); }else{ System.out.println("beforeHandshake运行结束 false"); return false; } } return true; } public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { super.afterHandshake(request, response, wsHandler, exception); }}
3.Socket处理器
package org.xdemo.example.websocket.websocket;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import org.springframework.stereotype.Component;import org.springframework.web.socket.CloseStatus;import org.springframework.web.socket.TextMessage;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.WebSocketMessage;import org.springframework.web.socket.WebSocketSession;import org.xdemo.example.websocket.entity.Message;import com.google.gson.Gson;import com.google.gson.GsonBuilder;/** * Socket处理器 * * @author Goofy * @Date 2015年6月11日 下午1:19:50 */@Componentpublic class MyWebSocketHandler implements WebSocketHandler { public static final Map<Long, WebSocketSession> userSocketSessionMap; static { userSocketSessionMap = new HashMap<Long, WebSocketSession>(); } /** * 建立连接后 */ public void afterConnectionEstablished(WebSocketSession session) throws Exception { Long uid = (Long) session.getAttributes().get("uid"); if (userSocketSessionMap.get(uid) == null) { userSocketSessionMap.put(uid, session);//当前登陆用户与登陆session相关联 } } /** * 消息处理,在客户端通过Websocket API发送的消息会经过这里,然后进行相应的处理 */ public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { if(message.getPayloadLength()==0)return; Message msg=new Gson().fromJson(message.getPayload().toString(),Message.class); msg.setDate(new Date()); sendMessageToUser(msg.getTo(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg))); } /** * 消息传输错误处理 */ public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { if (session.isOpen()) { session.close(); } Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap .entrySet().iterator(); // 移除Socket会话 while (it.hasNext()) { Entry<Long, WebSocketSession> entry = it.next(); if (entry.getValue().getId().equals(session.getId())) { userSocketSessionMap.remove(entry.getKey()); System.out.println("Socket会话已经移除:用户ID" + entry.getKey()); break; } } } /** * 关闭连接后 */ public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { System.out.println("Websocket:" + session.getId() + "已经关闭"); Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap .entrySet().iterator(); // 移除Socket会话 while (it.hasNext()) { Entry<Long, WebSocketSession> entry = it.next(); if (entry.getValue().getId().equals(session.getId())) { userSocketSessionMap.remove(entry.getKey()); System.out.println("Socket会话已经移除:用户ID" + entry.getKey()); break; } } } public boolean supportsPartialMessages() { return false; } /** * 给所有在线用户发送消息 * * @param message * @throws IOException */ public void broadcast(final TextMessage message) throws IOException { Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap .entrySet().iterator(); // 多线程群发 while (it.hasNext()) { final Entry<Long, WebSocketSession> entry = it.next(); if (entry.getValue().isOpen()) { // entry.getValue().sendMessage(message); new Thread(new Runnable() { public void run() { try { if (entry.getValue().isOpen()) { entry.getValue().sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } } } /** * 给某个用户发送消息 * * @param userName * @param message * @throws IOException */ public void sendMessageToUser(Long uid, TextMessage message) throws IOException { WebSocketSession session = userSocketSessionMap.get(uid); if (session != null && session.isOpen()) { session.sendMessage(message); } }}
PS:使用的是Tomcat8.5
https://github.com/Amant-huangqi/spring-websocket
阅读全文
0 0
- Spring-WebScoket
- spring+webscoket注解方式
- webscoket
- webScoket
- WebScoket 规范
- WebScoket 规范
- WebScoket 规范 + WebSocket 协议
- java webscoket聊天室
- webscoket rfc6455 中文版链接
- jmeter 测试webscoket
- SpringMVC整合webScoket总结
- webscoket 的定义
- WebScoket 规范 + WebSocket 协议
- WebScoket消息推送
- java使用webscoket小李子
- WebScoket通信简单小例子
- 基于tomcat的webscoket应用
- Webscoket的使用以及优化
- 我,一个正在成长的西门少年
- mongodb 安装部署
- 欢迎使用CSDN-markdown编辑器
- iOS开发算法--二叉树
- redmine配置邮箱提醒步骤(qq企业邮箱和个人邮箱)
- Spring-WebScoket
- java多线程—优先级反转问题
- C++/MFC-Spin
- Android热补丁之AndFix原理解析
- 【iOS】点击按钮Button,更变标签文字Label的颜色
- 【坑爹微信】微信JSSDK图片上传问题和解决
- 互联网架构(2):并发编程--并发编程的设计模式
- oracle设置某一个字段为当前时间
- jquery还原rowspan 并取数据