WebSocket实现多人在线聊天功能

WebSocket是现在最流行的实现多人在线聊或者私聊的技术,它可以实现客户端到客户端的通信,和以往的TCPUDP不一样,它俩是客户端到服务端的通信,而且服务端不能直接给客户端发送消息,但是WebSocket不仅可以客户端和客户端之间通信,服务端也可以直接发送消息给客户端。
下面实现的一个多人的在线聊天室,前台聊天框是在网上找的模板,该聊天室具有的功能如下

  1. 当一个客户端进入之后,其他客户端会看到系统消息提示(某某某进入了聊天室)
  2. 客户端发送消息,每个客户端都可以收到消息
  3. 当一个客户端退出或者关闭聊天室网页时,其他客户端会看到系统消息提示(某某某退出了聊天室)

下面是代码,这里说明一点
里面的注解像@ServerEndpoint@OnMessage@OnClose@OnOpen等都是javax支持的,还有下面的Session不是HTTPSession,都是属于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();
	}
}

然后聊天室就完工啦!

posted @ 2020-03-08 17:09  你樊不樊  阅读(667)  评论(0编辑  收藏  举报