woniyu 2020-03-08
WebSocket
是现在最流行的实现多人在线聊或者私聊的技术,它可以实现客户端到客户端的通信,和以往的TCP
和UDP
不一样,它俩是客户端到服务端的通信,而且服务端不能直接给客户端发送消息,但是WebSocket
不仅可以客户端和客户端之间通信,服务端也可以直接发送消息给客户端。
下面实现的一个多人的在线聊天室,前台聊天框是在网上找的模板,该聊天室具有的功能如下
下面是代码,这里说明一点
里面的注解像@ServerEndpoint
,@OnMessage
,@OnClose
,@OnOpen
等都是javax
支持的,还有下面的Session
不是HTTP
的Session
,都是属于javax.websocket
的。
项目是一个简单的Web
项目,什么框架也没用,只是复制了一个html
页面到WebContent
文件夹。
因为web.xml
文件的配置,所以把项目部署到Tomcat
上面直接运行,输入路径localhost:8080/chatroom
即可,默认跳转到index.html
页面,也就是聊天框的页面。
<welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list>
至于html
页面也不用我给你们了吧,自己可以在网上面找聊天模板,太多了。
直接讲js
吧?要模板的到最下面给你们链接去下载好啦,记得好评兄弟盟,如果帮到你们的话就给宝宝扣个1可否?
js
代码
<script type="text/javascript"> //webSocket实现聊天,客户端需要做的事情,总结起来,其实就是一下几件 //1,获取连接,new WebSocket() //服务端地址和请求类型 var wsUrl="ws://localhost:8080/chatroom/charRoomServer"; //客户端与服务端建立连接,建立连接以后,它会发出一个ws.open事件 var ws=new WebSocket(wsUrl); //连接成功后,提示浏览器客户端输入名称 ws.onopen=function(){ var userName=prompt("请给自己取一个名字"); ws.send(userName); } //客户端收到服务端发送的消息 ws.onmessage=function(message){ //获取以后,在客户端显示,messages是聊天内容的框的id messages.innerHTML+=message.data; } //获取某个用户输入的聊天内容,并发送到服务端,让服务端广播给所有人 function getMessage(){ var inputMessage=document.getElementById("inputMessage").value; //alert(inputMessage); //获取消息以后,要发送给服务端,然后广播给所有用户 if(typeof(inputMessage)=='undefined'){ alert("请输入您要发送的消息!"); }else{ ws.send(inputMessage); //输入框消息清空 inputMessage.value=""; } } //当关闭页面或者用户退出时,会执行一个ws.close()方法 window.onbeforeunload=function(){ ws.close(); } //按回车发送信息 document.onkeyup=function(e){ if(e.keyCode==13){ getMessage(); inputMessage.value=""; } } </script>
Java
代码
package com.fjf.chat; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; /** * 聊天室的服务端程序 * @author Administrator * */ //声明websocket某个服务端的地址 @ServerEndpoint("/charRoomServer") public class ChatRoomServer { private boolean firstFlag=true; private Session session; private String userName; //记录此次聊天室的服务端有多少个连接 //key代表此次客户端的session的id,value代表此次连接对象 private static final HashMap<String, Object> connectMap=new HashMap<String, Object>(); //保存所有用户昵称信息 //key是session的id,value是用户昵称 private static final HashMap<String, String> userMap=new HashMap<String, String>(); //服务端收到客户端的连接请求,连接成功后会执行此方法 @OnOpen public void start(Session session) { this.session=session; connectMap.put(session.getId(), this); } //客户端发来的信息,服务端接收 @OnMessage public void chat(String clientMessage,Session session) { //firstFlag为true是第一次进入,第二次进入之后设为false ChatRoomServer client=null; if(firstFlag) { this.userName=clientMessage; //将新进来的用户保存到用户map userMap.put(session.getId(), userName); //构造发送给客户端的提示信息 String message=htmlMessage("系统消息:",userName+"进入聊天室"); //将消息广播给给所有的用户 //Map.keySet()方法是获取到Map集合的所有的key值 for(String connectKey:connectMap.keySet()) { client=(ChatRoomServer) connectMap.get(connectKey); //给对应的web端发送一个文本信息 try { client.session.getBasicRemote().sendText(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } firstFlag=false; }else { //构造发送给客户端的提示信息 String message=htmlMessage(userMap.get(session.getId()),clientMessage); //将消息广播给给所有的用户 //Map.keySet()方法是获取到Map集合的所有的key值 for(String connectKey:connectMap.keySet()) { client=(ChatRoomServer) connectMap.get(connectKey); //给对应的web端发送一个文本信息 try { client.session.getBasicRemote().sendText(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 前台js的ws.close事件,会触发后台的标注onClose的方法 */ @OnClose public void close(Session session) { //当某个用户退出时,对其他用户进行广播 String message=htmlMessage("系统消息", userMap.get(session.getId())+"退出了聊天室"); userMap.remove(session.getId()); connectMap.remove(session.getId()); //将消息广播给给所有的用户 //Map.keySet()方法是获取到Map集合的所有的key值 ChatRoomServer client=null; for(String connectKey:connectMap.keySet()) { client=(ChatRoomServer) connectMap.get(connectKey); //给对应的web端发送一个文本信息 try { client.session.getBasicRemote().sendText(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 渲染页面,把信息构造好标签再发送 */ public String htmlMessage(String userName,String message) { StringBuffer stringBuffer=new StringBuffer(); SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); stringBuffer.append("<article>"); stringBuffer.append("<span>"+sf.format(new Date())+"</span>"); stringBuffer.append("<div class='avatar'>"); stringBuffer.append("<h3>"+userName+"</h3>"); stringBuffer.append("</div>"); stringBuffer.append("<div class='msg'>"); stringBuffer.append("<div class='tri'></div>"); stringBuffer.append("<div class='msg_inner'>"+message+"</div>"); stringBuffer.append("</div>"); stringBuffer.append("</article>"); return stringBuffer.toString(); } }
然后聊天室就完工啦!