WebSocket 聊天

定义一个WebSocket类

  • @ServerEndpoint:标记为一个WebSocket类,value指定url地址,可以通过{name}获取参数name值
  • @OnOpen、@OnClose、@OnMessage:连接、关闭、接收消息
  • Session:与某个客户端的连接会话,使用session.getBasicRemote().sendText()给客户端发送数据
  • Map<String, ChatSocket>:使用Map集合维护多个客户端连接集合,在连接成功时加入,连接断开时删除
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;


@ServerEndpoint(value = "/ws/chat/{username}")
public class ChatSocket {
	// 使用session对用户发送数据
	private Session session;
	private String name;
	
	// 客户端连接集合
	private static Map<String, ChatSocket> users = new ConcurrentHashMap<>();
	
	/**
	 * 客户端连接
	 * @param session
	 * @throws IOException
	 */
	@OnOpen
	public void open(Session session, @PathParam("username")String username) throws IOException{
		this.session = session; //每次客户端连接重置当前session
		this.name = username;
		users.put(username, this);//增加用户连接
		// 更新在线人数
		String messageFormat = "{\"msg\":\"%s\",\"total\":%d}";
		for (ChatSocket chat : users.values()){
			Date date = new Date();
			chat.sendMessage(String.format(messageFormat, date.toString()+"\t"+username+"\t登入", users.size()));
		}
	}
	
	/**
	 * 客户端关闭
	 * @param session
	 * @throws IOException 
	 */
	@OnClose
	public void close(Session session) throws IOException{
		//this.username = username;
		users.remove(name);  // 删除指定用户的key
		// 更新在线人数
		String messageFormat = "{\"msg\":\"%s\",\"total\":%d}";
		for (ChatSocket chat : users.values()){
			Date date = new Date();
			chat.sendMessage(String.format(messageFormat, date.toString()+"\t"+name+"\t退出", users.size()));
		}
	}
	
	/**
	 * 连接错误
	 * @param e
	 */
	@OnError
	public void error(Session s, Throwable e){
		e.printStackTrace();
	}
	
	/**
	 * 接受客户端发送来的消息
	 * @throws IOException 
	 */
	@OnMessage
	public void recMessage(String message, Session session) throws IOException{
		String messageFormat = "{\"msg\":\"%s\",\"total\":%d}";
		for (ChatSocket chat : users.values()){
			Date date = new Date();
			chat.sendMessage(String.format(messageFormat, date.toString()+"| \t"+name+"\t : "+message, users.size()));
		}
	}
	
	/**
	 * 向客户端发送消息
	 * @param message
	 * @throws IOException
	 */
	public void sendMessage(String message) throws IOException{
		session.getBasicRemote().sendText(message);
	}
}

和前端交互

  • new WebSocket("url"):生成WebSocket对象
  • window.onbeforeunload:监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常
  • if ('WebSocket' in window):判断浏览器是否支持WebSocket
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>

online number:<div id="num"></div><br/>
<input type="text" id="username" /> <input type="button" id="connect" title="connect" value="connect" onclick="getConnetion()"><br/>
<input type="text" id="content" /> <br/>
<input type="button" id="send" title="send" value="send" onclick="sendMsg()">
<div id="msg"></div>

<script type="text/javascript">
	var websocket = null;
    	
	function getConnetion(){
		var name = $("#username").val();
		if ('WebSocket' in window){
			    if (websocket == null){
			    	websocket = new WebSocket("ws://localhost:8080/bitcoin/ws/chat/"+name);
					
					// 连接成功回掉
					websocket.onopen = function(){
						//websocket.send("客户端连接成功");
					}
					
			        // 接收到消息的回掉方法
			        websocket.onmessage = function(event){
			        	recvMessage(event.data);
			        }
					
			        // 连接发生错误的回调方法
			        websocket.onerror = function () {
			            alert("WebSocket连接发生错误");
			        };
			 
			       // 连接关闭的回调方法
			        websocket.onclose = function () {
			            alert("WebSocket连接关闭");
			        }	
			    }
		    
		}
	}
	
    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket();
    }
	
    // 关闭WebSocket连接
    function closeWebSocket() {
    	websocket.close();
    }
    
	// 监听消息发送
	function sendMsg(){
		var con = $("#content").val();
		if (null != websocket){
			websocket.send(con);
		}
	}
	
    // 接收到服务器消息
	function recvMessage(innerHTML){
		var msg = eval("("+innerHTML+")");
		$("#num").html(msg.total);
		$("#msg").append("<div>"+msg.msg+"</div><br/>");
	}
	
	
	</script>
</body>
</html>
posted @ 2020-11-17 23:06  熊云港  阅读(193)  评论(0编辑  收藏  举报