zoukankan      html  css  js  c++  java
  • 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()+"	"+username+"	登入", 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()+"	"+name+"	退出", 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()+"| 	"+name+"	 : "+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>
    
  • 相关阅读:
    装饰器
    闭包函数
    名称空间与作用域
    函数参数 函数对象 函数嵌套
    文件内光标的移动 函数基础 定义函数的三种形式 函数的返回值 调用方式
    文件
    字符编码 文件处理
    人月神话之阅读笔记一
    mysql+servlet+jsp实现数据库的增删改查
    文件与流课后作业
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/13997335.html
Copyright © 2011-2022 走看看