JSR356标准Java WebSocket的使用示例(Tomcat9.0.6)

本篇记录说明

JSR356标准Java WebSocket的使用示例(Tomcat9.0.6)

一、前言
传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式 对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应用,比如QQ消息、淘宝购物后的系统消息等等。
在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,大多是使用HTTP请求的方式实现,主要有以下几种方式:

轮询方式:客户端定时向服务端发送ajax请求,服务器接收到请求后马上返回消息并关闭连接。
优点:后端程序编写比较容易。
缺点:TCP的建立和关闭操作浪费时间和带宽,请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用。

长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
实例:WebQQ、Hi网页版、Facebook IM。

长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
优点:消息即时到达,不发无用请求;管理起来也相对方便。
缺点:服务器维护一个长连接会增加开销,当客户端越来越多的时候,server压力大!
实例:Gmail聊天

Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
优点:实现真正的即时通信,而不是伪即时。
缺点:客户端必须安装Flash插件,移动端支持不好,IOS系统中没有flash的存在;非HTTP协议,无法自动穿越防火墙。
实例:网络互动游戏。

伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力。WebSocket的工作流程是这样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询小了很多。本文不详细地介绍WebSocket规范,主要介绍下WebSocket在Java Web中的实现。

Tomcat自7.0.5版本开始支持WebSocket,并且实现了Java WebSocket规范(JSR356 ),而在7.0.5版本之前(7.0.2版本之后)则采用自定义API,即WebSocketServlet。本文使用的是Tomcat9.0.6版本

二、示例
1、新建dynamic web project,项目名称WebSocketServletTest;
image.png

2、新建WebSocketEndpoint类;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/websocket/{user}")
public class WebSocketEndpoint {

	private Session session;

	@OnOpen
	public void open(Session session, @PathParam(value = "user") String user) {
		this.session = session;

		System.out.print("*** WebSocket opened from sessionId " + session.getId());
	}

	@OnMessage
	public void inMessage(String message) {
		System.out.print("*** WebSocket Received from sessionId " + this.session.getId() + ": " + message);
	}

	@OnClose
	public void end() {
		System.out.print("*** WebSocket closed from sessionId " + this.session.getId());
	}

}

3、新建websocket.html;

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Index</title>
		<script type="text/javascript">
			var ws = null;

			function startWebSocket() {
				if ('WebSocket' in window)
					ws = new WebSocket("ws://localhost:8080/WebSocketServletTest/websocket/user");
				else if ('MozWebSocket' in window)
					ws = new MozWebSocket("ws://localhost:8080/WebSocketServletTest/websocket/user");
				else
					alert("not support");


				ws.onmessage = function(evt) {
					alert(evt.data);
				};

				ws.onclose = function(evt) {
					alert("close");
				};

				ws.onopen = function(evt) {
					alert("open");
				};
			}

			function sendMsg() {
				ws.send(document.getElementById('writeMsg').value);
			}
		</script>
	</head>
	<body onload="startWebSocket();">
		<input type="text" id="writeMsg"></input>
		<input type="button" value="send" onclick="sendMsg()"></input>
	</body>
</html>

三、运行效果截图:
image.png

四、结语
以上JSR356标准Java WebSocket使用示例(Tomcat9.0.6)的流程,写得不好的地方见谅,面向新手,大佬请无视,不喜勿喷。

如果没有解决您的问题,可以添加微信交流:very2cc

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Websocket是HTML5中的一种协议,用于在客户端和服务器之间建立双向通信的连接,可以实现实时数据传输和互动。在Java中,可使用Java WebSocket API(JSR 356)实现Websocket功能。 以下是使用Java WebSocket API实现Websocket的代码示例: 1. 创建一个继承自javax.websocket.Endpoint的类,实现onOpen、onMessage、onClose和onError方法,用于处理Websocket连接的打开、消息接收、关闭和错误处理。 ``` import java.io.IOException; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.Session; import javax.websocket.CloseReason; public class MyEndpoint extends Endpoint { @Override public void onOpen(Session session, EndpointConfig config) { // 当Websocket连接打开时,执行此方法 System.out.println("Websocket connected: " + session.getId()); // 注册消息处理器 session.addMessageHandler(new MessageHandler.Whole<String>() { @Override public void onMessage(String message) { // 接收到消息时,执行此方法 System.out.println("Received message: " + message); // 发送消息给客户端 try { session.getBasicRemote().sendText("Hello, " + message); } catch (IOException e) { e.printStackTrace(); } } }); } @Override public void onClose(Session session, CloseReason reason) { // 当Websocket连接关闭时,执行此方法 System.out.println("Websocket closed: " + session.getId()); } @Override public void onError(Session session, Throwable throwable) { // 当Websocket连接出现错误时,执行此方法 throwable.printStackTrace(); } } ``` 2. 在Web应用程序中,使用javax.websocket.server.ServerEndpoint注解指定一个URI,将其绑定到MyEndpoint类上。例如: ``` import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/myendpoint") public class MyEndpoint { // ... } ``` 3. 在Web应用程序中,使用javax.websocket.server.ServerContainer类来注册MyEndpoint类。例如: ``` import javax.websocket.server.ServerContainer; import javax.websocket.server.ServerEndpointConfig; @javax.servlet.annotation.WebServlet(name = "MyWebsocketServlet", urlPatterns = {"/mywebsocket"}) public class MyWebsocketServlet extends javax.servlet.http.HttpServlet { @Override public void init() { // 获取ServerContainer对象 ServerContainer container = (ServerContainer)getServletContext().getAttribute("javax.websocket.server.ServerContainer"); // 创建EndpointConfig对象 ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(MyEndpoint.class, "/myendpoint").build(); // 注册Endpoint try { container.addEndpoint(endpointConfig); System.out.println("Websocket endpoint registered"); } catch (Exception e) { e.printStackTrace(); } } } ``` 4. 在客户端中,使用WebSocket对象来连接MyEndpoint类。例如: ``` var ws = new WebSocket("ws://localhost:8080/mywebsocket/myendpoint"); ws.onopen = function() { console.log("Websocket connected"); ws.send("World"); }; ws.onmessage = function(event) { console.log("Received message: " + event.data); }; ws.onclose = function(event) { console.log("Websocket closed: " + event.code); }; ``` 这样,就可以在客户端和服务器之间建立双向通信的Websocket连接,并实现数据传输和互动。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大麦147

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值