欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

websocket 的简单应用

程序员文章站 2022-05-21 13:43:54
...

今天我试着用websocket 搭建了一个简单的 网页即时通讯,记录一下步骤

引入必须包,我用的是maven

		<dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
        </dependency>

创建一个获取session 的类

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;

public class GetHttpSessionConfigurator extends Configurator {
	@Override
	public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request
			, HandshakeResponse response) {
		// TODO Auto-generated method stub
        HttpSession httpSession=(HttpSession) request.getHttpSession();
        sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
	}
}

创建一个 监听类

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;

public class RequestListener implements ServletRequestListener {

	@Override
	public void requestDestroyed(ServletRequestEvent sre) {
		// TODO Auto-generated method stub

	}

	@Override
	public void requestInitialized(ServletRequestEvent sre) {
		// TODO Auto-generated method stub
		((HttpServletRequest) sre.getServletRequest()).getSession();
	}

}
在web.xml 配置监听路径
  <listener>
        <listener-class>包路径.RequestListener</listener-class>
 </listener>

服务层

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.xueyou.common.GetHttpSessionConfigurator;
import com.xueyou.model.user.TbUser;

@Component
@ServerEndpoint(value="/onlinetalk",configurator = GetHttpSessionConfigurator.class)
public class WebSocketController {
	
	private static final Logger log = Logger.getLogger(WebSocketController.class);
	private static final Map<Integer, WebSocketController> connection 
		= new HashMap<Integer, WebSocketController>();
    private Integer userId;  
    private String nickname;  
    private Session session;  
    
    @OnOpen
    public void start(Session session,EndpointConfig config) {  
        //获取HttpSession对象  
    	HttpSession httpSession = (HttpSession) config.getUserProperties()
    			.get(HttpSession.class.getName());
    	TbUser user = (TbUser) httpSession.getAttribute("loginUser");
    	Integer uid = user.getUserId();
    	this.userId = uid;  
        this.nickname = user.getNickName();  
        this.session = session;  
          /*判断链接是否已经在链接队列中,存在就不加*/  
        if(!connection.containsKey(uid)){  
            connection.put(uid, this);  
            String message = "* 您已上线";  
            toConfirmFriend(message,uid);  
        }  
     } 
    
    @OnClose  
    public void end() {  
        connection.remove(this.userId);  
        String message = "* 您已下线";  
        toConfirmFriend(message,this.userId); 
    }
    
    @OnMessage  
    public void incoming(String message){  
    	String[] all = message.split("_");
    	String[] ids = all[1].split("::");
    	//这是为了群发准备的
    	List<String> list = Arrays.asList(ids);
        //要接收消息好友的ID  
        list.forEach(uid -> {
            //判断好友的连接是否存在,不存在就提示好友掉线  
        	Integer id = Integer.parseInt(uid);
            if(connection.containsKey(id)){  
                 String filteredMessage = String.format("%s: %s",  
                            this.nickname, all[0]);  
                    sendCommonRecord(filteredMessage,id,this.userId);  
            }else{
                String filteredMessage = String.format("* %s", "对方不在线");
            	toConfirmFriend(filteredMessage,this.userId);
            }
        }); 
    }
    
    @OnError  
    public void onError(Throwable t) throws Throwable {  
        log.error("Chat Error: " + t.toString(), t);  
    } 
    
	//发送给指定的好友  
    private static void toConfirmFriend(String msg,Integer userId2) {  
    	WebSocketController client = connection.get(userId2);  
        try {  
            synchronized (client) {  
                client.session.getBasicRemote().sendText(msg);  
            }  
        } catch (IOException e) {  
            log.debug("Chat Error: Failed to send message to "+client.nickname, e);  
            try {  
                client.session.close();  
            } catch (IOException e1) {  
                // Ignore  
            }  
        }  
    } 
    
    //给聊天的双发发共同消息  
    private static void sendCommonRecord(String msg,Integer sid,Integer gid) {  
    	WebSocketController client_send = connection.get(sid);  
    	WebSocketController client_get = connection.get(gid);  
        try {  
            synchronized (client_send) {  
                client_send.session.getBasicRemote().sendText(msg);  
            }  
            //将这条聊天记录保存在数据库    
            /**/
        } catch (IOException e) {  
            log.debug("Chat Error: Failed to send message to "+client_send.nickname, e);  
            connection.remove(sid);  
            try {  
                client_send.session.close();  
            }catch (IOException e1) {  
                // Ignore  
            }  
        }  
        try {  
            synchronized (client_get) {  
                client_get.session.getBasicRemote().sendText(msg);  
            }  
        } catch (IOException e) {  
            log.debug("Chat Error: Failed to send message to "+client_get.nickname, e);  
            connection.remove(gid);  
            try {  
                client_get.session.close();  
            } catch (IOException e1) {  
                // Ignore  
            }  
        }  
    } 
}
jsp 页面,记得引用 jquery
<%@ 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>
</head>
<body>
	<div class="content"
		style="border-radius: 10px; width: 100%; height: 70%; border: 5px solid;
    overflow-y: overlay;
    overflow-x: hidden;"></div>
	<div
		style="border-radius: 10px; width: 100%; height: 30%; border: 5px solid;">
		<textarea style="width: 100%; height: 100%" class="sendmsg"></textarea>
	</div>
	<input type="hidden" id="fid" value="${sessionScope.loginUser.userId }" />
	<script type="text/javascript">
		(function($) {
			var Chat = {};
			Chat.socket = null;
			// 创建一个websocket实例  
			Chat.connect = (function(host) {
				if ('WebSocket' in window) {
					Chat.socket = new WebSocket(host);
				} else if ('MozWebSocket' in window) {
					Chat.socket = new MozWebSocket(host);
				} else {
					alert('你的浏览器不支持在线聊天');
					return;
				}
				Chat.socket.onopen = function() {
					/* Content.print('Console.log:WebSocket链接打开'); */
				};
				Chat.socket.onclose = function() {
					/* Content.print('Console.log:WebSocket前端链接关闭'); */
				};
				Chat.socket.onmessage = function(message) {
					Content.print(message.data);
				};
			});

			//按下回车键发送消息  
			$('.sendmsg').on('keyup', function(event) {
				if ((event.keyCode || event.which) === 13) {
					if(Chat.socket.readyState === 1){
						Chat.sendMessage();
					}
				}
			});
			Chat.initialize = function() {
				//链接地址选择聊天页面的URL    
				if (window.location.protocol === 'http:') {
					Chat.connect("ws://" + window.location.host
									+ "/onlinetalk");
				} else {
					Chat.connect("wss://" + window.location.host
							+ "/onlinetalk");
				}
			};
			//发送消息函数,后面动态添加了发送好友的唯一ID   
			Chat.sendMessage = (function() {
				var fid = $("#fid").val();
				var ids = 0;
				if (fid == 2685) {
					ids = 1522 + '::';
				} else {
					ids = 2685 + '::';
				}
				var messageContain = $('.sendmsg').val().toString();
				var message = messageContain + '_' + ids;
				if (fid === "") {
					alert("未选择发送消息的好友!");
					return;
				} else {
					if (messageContain !== "") {
						Chat.socket.send(message);
						$('.sendmsg').val('');
					} else {
						alert("发送消息不能为空!");
					}
				}
			});
			var Content = {};
			Content.print = (function(message) {
				var p = '<p style="word-wrap:break-word;">' + message + '</p>';
				$('.content').append(p);
				$('.content').scrollTop( $('.content')[0].scrollHeight);
			});
			//初始化函数  
			Chat.initialize();
			//关闭页面前 关闭连接
			window.onbeforeunload = function() {
				Chat.socket.close();
			}
		})(jQuery);
	</script>
</body>
</html>

上效果图

websocket 的简单应用

websocket 的简单应用