Java WebSocket的简单使用

Java WebSocket的简单使用

此案例主要使用WebSocket实现代理系统发布公告时,App端可以实时显示出来

代码:

前台
  • App端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>

	<body>
		<h1>App手机客户端</h1>
		<div id="">
			<ul id="notice">
			</ul>
		</div>
		<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
		<script type="text/javascript">
			//向公告内容里面插入新公告
			function addNotice(content) {
				//向ul>li插入公告
				var ul = $('#notice').append('<li>' + content + '</li>')
			}

			//初始化WebSocket连接
			//判断当前浏览器是否支持WebSocket  
			if('WebSocket' in window) {
				console.log('浏览器支持WebSocket')
				websocket = new WebSocket("ws://192.168.0.118:8085/myssh/websocket/server/app");
			} else {
				alert('当前浏览器不支持 websocket')
			}
			
			//连接发生错误的回调方法  
			websocket.onerror = function() {
				console.log("WebSocket连接发生错误");
			};

			//连接成功建立的回调方法  
			websocket.onopen = function() {
				websocket.send('APP客户端连接成功');
			}

			//接收到消息的回调方法  
			websocket.onmessage = function(event) {
				addNotice(event.data);
			}

			//连接关闭的回调方法  
			websocket.onclose = function() {
				console.log("WebSocket连接关闭");
			}

			//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。  
			window.onbeforeunload = function() {
				closeWebSocket();
			}

			//关闭WebSocket连接  
			function closeWebSocket() {
				websocket.close();
			}
		</script>
	</body>
</html>
  • 代理
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
		<h1>后台管理系统</h1>
		<span id="">
			此案例主要使用WebSocket实现后台管理系统发布公告时,App端可以实时显示出来
		</span>
		<hr />
		<input id="msg" placeholder="公告内容"/>
		<input type="button" value="发送" id="send"/>
		
		
		<script type="text/javascript" src="js/jquery-1.9.1.min.js" ></script>
		<script type="text/javascript">
			//判断当前浏览器是否支持WebSocket  
			if('WebSocket' in window) {
				console.log('浏览器支持WebSocket')
				websocket = new WebSocket("ws://192.168.0.118:8085/myssh/websocket/server/代理");
			} else {
				alert('当前浏览器不支持 websocket')
			}

			//连接发生错误的回调方法  
			websocket.onerror = function() {
				console.log("WebSocket连接发生错误");
			};

			//连接成功建立的回调方法  
			websocket.onopen = function() {
				websocket.send('代理端连接成功');
			}

			//接收到消息的回调方法  
			websocket.onmessage = function(event) {
				console.log(event.data)
			}

			//连接关闭的回调方法  
			websocket.onclose = function() {
				console.log("WebSocket连接关闭");
			}

			//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。  
			window.onbeforeunload = function() {
				closeWebSocket();
			}

			//关闭WebSocket连接  
			function closeWebSocket() {
				websocket.close();
			}
			
			
			/**
			 * 发布公告
			 */
			$('#send').click(()=>{
				//alert(1)
				//获取公告内容
				websocket.send($('#msg').val());
			})
			
		</script>
	</body>
</html>

后台[就只有一个类,使用的是tomcat的websocket实现,文章结尾会介绍其他方法]
package com.ssh.socket;

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;

/**
 * 后台管理系统发布公告
 * @author asus
 *
 */
/**
 * @ServerEndpoint和springMVC @RequestMapping有点像,就是一个用来处理http/https请求的,一个是用来处理ws/wss请求的
 * "/websocket/server/{username}"这个也是对应的前端的请求地址:"ws://192.168.0.118:8085/myssh/websocket/server/代理"
 * 前端请求webSocket就不是使用http了,而是ws
 * {username}对应的就是“代理”了,这种写法是为了获取前端请求路径上面的参数,这里必须要写,否则下面的@PathParam("username")获取不到参数
 */
@ServerEndpoint("/websocket/server/{username}")
public class WebSocketServer {
	
	//用于存放所有连接进来的客户端
	private static Map<String, WebSocketServer> clients = new ConcurrentHashMap<String, WebSocketServer>();  
	
	private Session session;  
    private String username; 
	
	@OnOpen  
	public void onOpen(@PathParam("username") String username, Session session) {  
		session.getAsyncRemote().sendText("服务器接收到了客户端的连接请求!");
		
		this.username = username;
		this.session = session;
		
		clients.put(username, this);
	}  

	@OnClose  
	public void onClose() {  
		System.out.println("后台管理系统已关闭连接");  
	}  

	@OnMessage  
	public void onMessage(@PathParam("username") String username, String message)  {  
		System.err.println("接收到客户端的消息:" + message);
		/**
		 * 通知所有人[包括代理和用户]
		 */
		for (WebSocketServer item : clients.values()) {
            item.session.getAsyncRemote().sendText(this.username + " : " + message);  
        }  
	}  

	@OnError  
	public void onError(Session session, Throwable error) {  
		error.printStackTrace();  
	}  
}


讲解

实际上是两个前端都连接至后台,然后后台将两个客户端都存入Map集合中,当然也可以自己定义一个类来存放用户和代理的信息,可以用来区分连接进来的是代理还是用户,此案例中没有进行代理和用户之间的区分,只是单纯的实现代理实时向用户[客户端]发送消息,发送消息就是通过循环去发送[因为之前已经把所有用户都存入Map],相当于每个连接进来的用户都是一个独立的连接,如果自己添加什么东西进行区分代理和用户,也可以在此基础上实现只给用户发送消息。

其他方法参考
Java后端WebSocket的Tomcat实现

posted @ 2019-04-03 21:00  leigq  阅读(474)  评论(0编辑  收藏  举报