原生的webscoket使用,最低要求tomcat7,并且查询tomcat的lib下是否存在webscoket*.jar,务必保证(apache-tomcat-7.0.78\lib)存在这两个jar包,否则不支持webscoket功能(也可能有其他实现思路,请赐教...):说明:我使用的tomcat7+jdk1.8;
本说明,使用注解的方式实现的简易及时聊天,其他功能,自行开发...
mavn依赖pom.xml:其中使用到了阿里的fastjson
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.38</version> </dependency>
<!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket --> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.0</version> </dependency>
因为我自己的项目跑不起来,所以单独配置了一下:
<build>
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <!--换个版本--> <target>1.8</target> <!--换个版本--> </configuration> </plugin> </plugins>
</build>
1、实现 ServerApplicationConfig
public class WebSocketConfig implements ServerApplicationConfig{ /** * 配置实现 * @Author wugong * @Date 2017/12/30 20:46 * @Modify if true,please enter your name or update time * @param */ @Override public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> set) { return null; } /** * 注解实现 * @Author wugong * @Date 2017/12/30 20:45 * @Modify if true,please enter your name or update time * @param */ @Override public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> set) { // 这里是注入当前项目中的所有的websocket服务,可以进行过过滤操作 return set; } }
2、注解实现websocket类
@ServerEndpoint("/demoAnnotation") public class DemoChat { private Session session;// 此session非servlet中的session,是获取不到当前登录人的信息的 private String userName; private Long userId; private static Set<DemoChat> demoChatSet = new HashSet<DemoChat>(); private static List<Session> onLineSession = new ArrayList<Session>(); // private static List<User> onLineUserList = new ArrayList<>(); private static List<String> onLineUserNameList = new ArrayList<String>();// 在线用户名 private static Map<Long,Session> onLineSessionMap = new HashMap<>();// 用户(session)与管道的关系 @OnOpen public void openTunnel(Session session){ // 我上线啦,通知所有在线的用户:只要是导致管道重新打开就会走这个方法 System.out.println("专用通道开启,有人来了..."); ChatMessage chatMessage = new ChatMessage(); String queryString = session.getQueryString(); System.out.println(queryString); this.userId = Long.valueOf(new Random().nextInt(100));; this.userName = "游客" + this.userId; this.session = session; demoChatSet.add(this); onLineSessionMap.put(this.userId,this.session); chatMessage.setFromUserName(this.userName); chatMessage.setFromUserId(this.userId); chatMessage.setToUserId(-1L); onLineUserNameList.add(this.userName); String msgText = "欢迎:"+this.userName+"进入房间,请开始你的表演..."; chatMessage.setMsgText(msgText); // 通知所有人在线的人 this.broadcast(this.demoChatSet,JSON.toJSONString(chatMessage)); } @OnClose public void closeTunnel(Session session){ // 我下线啦,通知所有在线用户 System.out.printf("管道关闭,有人退场....."); demoChatSet.remove(this); onLineSessionMap.remove(this.userId); onLineUserNameList.remove(this.userName); ChatMessage chatMessage = new ChatMessage(); chatMessage.setFromUserName(this.userName); chatMessage.setFromUserId(this.userId); chatMessage.setToUserId(-1L); String msgText = "欢送:"+this.userName+"离开房间,大家继续嗨..."; chatMessage.setMsgText(msgText); onLineUserNameList.add(this.userName); // msgText 通知所有人在线的人 this.broadcast(this.demoChatSet,JSON.toJSONString(chatMessage)); } @OnMessage public void receiveMessage(Session session,String msg){ try { ChatMessage chatMessage = JSON.parseObject(msg,ChatMessage.class); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String nowDateStr = simpleDateFormat.format(new Date()); chatMessage.setMsgText(nowDateStr+":"+chatMessage.getMsgText()+" from "+this.userName); chatMessage.setFromUserName(this.userName); chatMessage.setToUserId(null==chatMessage.getToUserId()?-1:chatMessage.getToUserId()); // 广播 if(-1 == chatMessage.getToUserId()){ // 广播给所有的人 this.broadcast(this.demoChatSet,chatMessage); // 发送给指定的人 }else{ // 获取当前的指定用户 if(onLineSessionMap.containsKey(chatMessage.getToUserId())){ Session thisSession = onLineSessionMap.get(chatMessage.getToUserId()); thisSession.getBasicRemote().sendText(JSON.toJSONString(chatMessage)); }else{ chatMessage.setMsgText(nowDateStr+"用户已经下线"); this.session.getBasicRemote().sendText(JSON.toJSONString(chatMessage)); } } } catch (Exception e) { e.printStackTrace(); } } /** * 进行广播消息 * @Author wugong * @Date 2017/12/30 21:51 * @Modify if true,please enter your name or update time * @param */ public void broadcast(Set<DemoChat> demoChatSet , ChatMessage chatMessage){ for (Iterator iterator = demoChatSet.iterator(); iterator.hasNext();) { DemoChat demoChat = (DemoChat) iterator.next(); try { demoChat.session.getBasicRemote().sendText(JSON.toJSONString(chatMessage)); } catch (IOException e) { e.printStackTrace(); } } } /** * 进行广播消息 * @Author wugong * @Date 2017/12/30 21:51 * @Modify if true,please enter your name or update time * @param */ public void broadcast(Set<DemoChat> demoChatSet , String msg){ for (Iterator iterator = demoChatSet.iterator(); iterator.hasNext();) { DemoChat demoChat = (DemoChat) iterator.next(); try { demoChat.session.getBasicRemote().sendText(msg); } catch (IOException e) { e.printStackTrace(); } } } }
辅助类:
public class User { private Long userId; private String userName; private Session session;
public class ChatMessage { private String msgText; private Integer msgType; private Long toUserId; private Long fromUserId; private String toUserName; private String fromUserName; private Long groupId;// 组ID private Integer chatType;// 聊天类型 1:单聊 2:多聊
3、jsp页面 webchat.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>websocket简易聊天</title> <style type="text/css"> input#chat { width: 410px } #console-container { width: 400px; } #console { border: 1px solid #CCCCCC; border-right-color: #999999; border-bottom-color: #999999; height: 170px; overflow-y: scroll; padding: 5px; width: 100%; } .user_list{ border: 1px solid #CCCCCC; border-right-color: #999999; border-bottom-color: #999999; height: 170px; overflow-y: scroll; padding: 5px; width: 280px; } #console p { padding: 0; margin: 0; }</style> </head> <body> <div class="noscript"><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable Javascript and reload this page!</h2></div> <div style="width: 100%;"> <p> <label>发送给userId:</label><input id="toUserId" placeholder="请输入游客id"> <input type="text" placeholder="type and press enter to chat" id="chat" /> </p> <div id="console-container" style="float: left"> <label>聊天区</label> <div id="console"></div> </div> <div style="float: left;margin-left: 12px;width: 300px;"> <label>在线用户</label> <div class="user_list"> 这里显示在线用户 </div> </div> </div> </body> <script type="text/javascript" src="${ctx}/js/jquery/jquery.min.js"></script> <script type="application/javascript"> var Chat = {}; Chat.socket = null; Chat.connect = (function(host) { if ('WebSocket' in window) { Chat.socket = new WebSocket(host); } else if ('MozWebSocket' in window) { Chat.socket = new MozWebSocket(host); } else { Console.log('Error: WebSocket is not supported by this browser.'); return; } // 管道开启shi Chat.socket.onopen = function () { Console.log('Info: WebSocket connection opened.'); document.getElementById('chat').onkeydown = function(event) { if (event.keyCode == 13) { Chat.sendMessage(); } }; }; // 管道关闭时 Chat.socket.onclose = function () { document.getElementById('chat').onkeydown = null; Console.log('Info: WebSocket closed.'); }; // 接收到消息时,进行处理显示 Chat.socket.onmessage = function (message) { eval("var result="+event.data); Console.log(result.msgText); }; }); Chat.initialize = function() { if (window.location.protocol == 'http:') { Chat.connect('ws://' + window.location.host + '/demoAnnotation?userId=1'); } else { Chat.connect('wss://' + window.location.host + '/demoAnnotation?userId=1'); } }; Chat.sendMessage = (function() { var message = document.getElementById('chat').value; if (message != '') { var toUserId = document.getElementById('toUserId').value; if(''==toUserId||null==toUserId||typeof(toUserId)==undefined){ toUserId = -1; } var msgJson = { chatType: 1, toUserId: toUserId, msgText: message }; message = JSON.stringify(msgJson); Chat.socket.send(message); document.getElementById('chat').value = ''; } }); var Console = {}; Console.log = (function(message) { var console = document.getElementById('console'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); while (console.childNodes.length > 25) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; }); Chat.initialize(); document.addEventListener("DOMContentLoaded", function() { // Remove elements with "noscript" class - <noscript> is not allowed in XHTML var noscripts = document.getElementsByClassName("noscript"); for (var i = 0; i < noscripts.length; i++) { noscripts[i].parentNode.removeChild(noscripts[i]); } }, false); </script> </html>
5、结果演示:(很多功能没与完善,自行完善即可)