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

Play框架写一个简单的websocket

程序员文章站 2022-04-18 11:51:49
...

1.创建一个websocket服务端
package Utils.websocket;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/***
*
* Websocket服务类
*
* @author user
*
*/
public class WebsocketServersg extends WebSocketServer {

		public static final Map<WebSocket, String> usercon = new HashMap<WebSocket, String>();
	
		
		public static Map<WebSocket, String> getUsercon() {
			return usercon;
		}
	
		public WebsocketServersg() throws UnknownHostException {
			
		}
	
		public WebsocketServersg(int port) throws UnknownHostException {
			super(new InetSocketAddress(port));
			System.out.println("websocket Server start at port:" + port);
		}
	
		/**
		 * 触发连接事件
		 */
		@Override
		public void onOpen(WebSocket conn, ClientHandshake clientHandshake) {
			System.out.println("新的客户端正在链接(onOpen)...:"
					+ conn.getRemoteSocketAddress().getAddress().getHostAddress());
		}
	
		/**
		 * 
		 * 连接断开时触发关闭事件
		 */
		@Override
		public void onClose(WebSocket conn, int code, String reason, boolean remote) {
	
			System.out.println("客户端关闭链接(onClose):" + usercon.get(conn));
			
			// 客户端断开连接就删除预存的WebSocket链接
			WebsocketServersgPool.removeUser(conn);
		}
	
		/**
		 * 
		 * 客户端发送消息到服务器时触发事件
		 * 
		 * @param conn
		 *            :客户端链接的信息
		 * @param message
		 *            :链接的用户账号
		 */
		@Override
		public void onMessage(WebSocket conn, String message) {
			System.out.println("新的客户端消息请注意(onMessage): " + message);
	
			// 将客户端链接服务端的信息暂时保存在usercon这个Map中,便于用java后台调用给客户端发送消息
			if(!WebsocketServersgPool.getCilentUser().containsKey(conn)){
				WebsocketServersgPool.addUser(message, conn);//添加客户端链接
			}
	
			// 向客户端发送消息
			//conn.send(message);
		}
	
		/**
		 * 触发异常事件
		 */
		@Override
		public void onError(WebSocket conn, Exception e) {
			if (conn != null) {
				System.out.println("发生异常");
			}
		}
	
		/**
		 * Main启动服务端
		 * 
		 * @param args
		 * @throws UnknownHostException
		 */
		public static void main(String[] args) throws UnknownHostException {
			
			new WebsocketServersg(9009).start();
		}
	
		/**
		 * 
		 * 启动服务端
		 * 
		 */
		public static void openingWebsocket() {
			System.out.println("websocket服务开启:" + 9009);
			try {
				new WebsocketServersg(9009).start();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
		/**
		 * 
		 * 关闭服务端
		 * 
		 */
		public static void closeWebsocket() {
			System.out.println("websocket服务关闭:" + 9009);
			try {
				new WebsocketServersg(9009).stop();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

2.创建一个websocket连接池
package Utils.websocket;

	import java.util.ArrayList;
	import java.util.Collection;
	import java.util.HashMap;
	import java.util.List;
	import java.util.Map;
	import java.util.Set;
	
	import org.java_websocket.WebSocket;
	/**
	 * 
	 * Websocket连接池
	 * 
	 * @author user
	 *
	 */
	public class WebsocketServersgPool {
	
		/**
		 * 连接池
		 */
		private static final Map<WebSocket,String> usercon = new HashMap<WebSocket,String>();
	
		/**
		 * 
		 * 获取所有的websocket客户端链接
		 * 
		 * @return
		 */
		public static Map<WebSocket,String> getCilentUser(){
			return usercon;	//添加连接
		}
		
		/**
		 * 向连接池中添加连接
		 * @param inbound
		 */
		public static void addUser(String user, WebSocket conn){
			usercon.put(conn,user);	//添加连接
		}
		
		/**
		 * 获取所有客户端
		 * @return
		 */
		public static Collection<String> getOnlineUser(){
			List<String> setUsers = new ArrayList<String>();
			Collection<String> setUser = usercon.values();
			for(String u:setUser){
				setUsers.add(u);
			}
			return setUsers;
		}
		
		/**
		 * 根据登陆者账号移除连接池中的连接
		 * @param inbound
		 */
		public static String userByRemoveUser(String userID){
			
			for (WebSocket wsds : usercon.keySet()) {
				if(usercon.get(wsds) == userID){
					removeUser(wsds);
				}
			}
			return "";
		}
		
		/**
		 * 移除连接池中的连接
		 * @param inbound
		 */
		public static boolean removeUser(WebSocket conn){
			if(usercon.containsKey(conn)){
				usercon.remove(conn);	//移除连接
				return true;
			}else{
				return false;
			}
		}
		
		/**
		 * 向指定的客户端发送数据
		 * @param user
		 * @param message
		 */
		public static void sendMessageToUser(WebSocket conn, String message){
			if(null != conn){
				conn.send(message);
			}
		}
		
		/**
		 * 向所有的客户端发送消息
		 * @param message
		 */
		public static void sendMessage(String message){
			Set<WebSocket> keySet = usercon.keySet();
			synchronized (keySet) {
				for (WebSocket conn : keySet) {
					String user = usercon.get(conn);
					if(user != null){
						conn.send(message);
					}
				}
			}
		}
	}

3.JS部分,在进行到页面,执行下边js
/**
*
* 启动websocket
*
*/
var ws;
function WebSocketOpening(){
if (“WebSocket” in window){
//alert(“您的浏览器支持 WebSocket!”);
// 创建一个 websocket
ws = new WebSocket(“ws://localhost:9009”);
ws.onopen = function(){
// Web Socket 已连接上,使用 send() 方法发送数据
//ws.send(“websocket已连接11111”);
console.log(“websocket已连接”);
//添加这个需要每隔账号对应单独的websocket客户端链接信息
ws.send(’${session.get(“zhanghao”)}’);
// alert(“数据发送中…”);
};

				ws.onmessage = function (evt){ 
					//后台有消息,前台进行接收
					var received_msg = evt.data;
					console.log("websocket接收:"+received_msg);
					
					//接收消息后执行的js
					websocketMessage(received_msg);

// alert(“数据已接收…” + received_msg);
};
ws.onclose = function(){
// 关闭 websocket
// alert(“连接已关闭…”);
console.log(“websocket连接已关闭…”);
};
}else{
// 浏览器不支持 WebSocket
alert(“您的浏览器不支持 WebSocket!”);
}
}
/**
*
* websocket消息
*
/
function websocketMessage(messageInfo){
alert(“接收到消息了:”+messageInfo);
}
4.java后台给客户端发送消息
/
*
* 根据userID给这个用户发送消息
*
* @param userID: 用户账号
* @param type: one:单个人;all:所有人
* @param message:要发送的消息
*
*/
public static void sendWebsocketMess(String userID, String type, String message){
Map<WebSocket, String> wsobj = WebsocketServersgPool.getCilentUser();
System.out.println(“客户端链接数:” + wsobj.keySet().size());
// usercon:所有客户端链接上都会存储这个Map中
for (WebSocket wsg : wsobj.keySet()) {
//wsg.send(messageInfo);
//判断账号是否一样,给特定的用户发送提示消息
if(“one”.equals(type) && wsobj.get(wsg) != null && wsobj.get(wsg).equals(userID)){
WebsocketServersgPool.sendMessageToUser(wsg, message);
}else if(“all”.equals(type)){
WebsocketServersgPool.sendMessage(message);
break;
}
}
}