文档章节

2.WebSocket编程—生命周期

巧乐兹
 巧乐兹
发布于 2016/10/27 23:50
字数 1091
阅读 34
收藏 0

WebSocket的生命周期

    WebSocket的端点,以事件的角度看,有四个生命周期事件:

  1. 打开事件:此事件发生在端点上建立连接时并且在任何其他事件发生之前;
  2. 消息事件:此事件在接收WebSocket对话中另一端发送的消息。它可以发生在WebSocket端点接收了打开事件之后并且在接收关闭事件关闭之前的任何时刻发生;
  3. 错误事件:此事件在WebSocket连接或端点发生错误时发生;
  4. 关闭事件:此事件在WebSocket连接或者端点发生错误时发生;

    以注解来声明这的话,可以用@OnOpen、@OnMessage、@OnError和@OnClose这四个注解。

    以一个例子来体现WebSocket的生命周期:

    点击打开连接按钮,与端点进行连接,这个时候会执行@OnOpen修饰的函数。

    点击发送消息,向端点发送文本框中的内容,这个时候会执行@OnMessage修饰的函数。

    点击关闭客户端连接按钮,客户端终端与端点的连接,这个时候会调用@OnClick修饰的函数。

    点击关闭服务端连接:

    端点关闭连接,关闭时大多数会产生一个异常会执行由@OnError修饰的函数,具体代码如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cn.net.bysoft</groupId>
	<artifactId>websocketapp</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<!-- servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/javax/javaee-api -->
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api -->
		<dependency>
			<groupId>javax.websocket</groupId>
			<artifactId>javax.websocket-api</artifactId>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>

</project>

    服务端代码:

package cn.net.bysoft.websocketapp.lesson2;

import java.io.IOException;

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;

@ServerEndpoint("/lifecycle")
public class LifeCycle {

	private static String START_TIME = "Start Time";
	private Session ws_session;

	@OnOpen
	public void onOpen(Session ws_session) {
		// 设置session,并记录建立连接时间
		this.ws_session = ws_session;
		ws_session.getUserProperties().put(START_TIME, System.currentTimeMillis());
		// 通知客户端连接成功
		this.sendMessage("success:opened.");
	}

	@OnMessage
	public void onMessage(String message) {
		// 如果客户端发送过来close,则关闭连接
		if ("close".equals(message)) {
			try {
				// 关闭前向客户端发送消息
				this.sendMessage("danger:server closing after " + this.getConnectionSeconds() + "s.");
				// 关闭连接
				ws_session.close();
			} catch (IOException e) {
				System.out.println("Method: onMessage, Error closeing session " + e.getMessage());
			}
			return;
		}
		// 如果消息不是close,则正常处理,处理完毕后通知客户端
		this.sendMessage("info:processed a message.");
	}

	@OnError
	public void onError(Throwable t) {
		// 发生异常时,如果连接还是打开状态,则通知客户端错误信息
		if (ws_session.isOpen()) {
			this.sendMessage("warning:Error:" + t.getMessage());
		}
	}

	@OnClose
	public void onClose() {
		// 关闭连接时,需要做的事情在该函数内完成,例如关闭数据库连接等
		System.out.println("serivce close.");
	}

	private void sendMessage(String message) {
		try {
			// 以同步的方式向客户端发送消息
			ws_session.getBasicRemote().sendText(message);
		} catch (IOException e) {
			System.out.println("Method: sendMessage, Error closeing session " + e.getMessage());
		}
	}

	private int getConnectionSeconds() {
		long millis = System.currentTimeMillis() - ((Long) this.ws_session.getUserProperties().get(START_TIME));
		return (int) millis / 1000;
	}
}

    客户端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet"
	href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
<!-- 可选的Bootstrap主题文件(一般不用引入) -->
<link rel="stylesheet"
	href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap-theme.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</head>
<body>
	<div class="container">
		<h1>WebSocket的生命周期</h1>
		<div class="row">

			<div class="col-md-12">
				<p>
					<button type="button" class="btn btn-primary"
						onclick="open_connection()">打开连接</button>
					<button type="button" class="btn btn-danger"
						onclick="closeServer()">关闭服务端连接</button>
					<button type="button" class="btn btn-danger"
						onclick="closeClient()">关闭客户端连接</button>
				</p>
			</div>
		</div>
		<div class="row">
			<form class="form-inline" role="form">
				<div class="col-md-12">
					<div class="form-group">
						<div class="input-group">
							<div class="input-group">
								<span class="input-group-addon"><span
									class="glyphicon glyphicon-send"></span></span> <input id="txtMessage"
									type="text" class="form-control" placeholder="Send Message">
							</div>
							<button type="button" class="btn btn-info"
								onclick="messageClick()">发送消息</button>
						</div>
					</div>
				</div>
			</form>
		</div>
		<div class="row">
			<div class="col-md-12">
				<p id="output">
					<br>
				</p>
			</div>
		</div>
	</div>
</body>
<script>
	var lifecycle_websocket = null;

	function init() {
		output = document.getElementById("output");
	}
	
	function dispose() {
		lifecycle_websocket.close();
		lifecycle_websocket = null;
	}

	function open_connection() {
		if (lifecycle_websocket == null) {
			lifecycle_websocket = new WebSocket(
					"ws://localhost:8080/websocketapp/lifecycle");

			lifecycle_websocket.onmessage = function(evt) {
				displayMessage(evt.data);
			}
			lifecycle_websocket.onclose = function(evt) {
				displayMessage(evt.data);
			}
			lifecycle_websocket.onerror = function(evt) {
				displayMessage(evt.data);
			}
		}
	}

	function messageClick() {
		send_message(document.getElementById("txtMessage").value);
	}

	function closeServer() {
		send_message("close");
	}

	function closeClient() {
		lifecycle_websocket.close();
		displayMessage("danger:client closed.")
	}

	function send_message(message) {
		lifecycle_websocket.send(message);
	}

	function displayMessage(message) {
		var flag = message.substring(0, message.indexOf(':'));
		var data = message.substring(message.indexOf(':') + 1);

		var pre = document.createElement("p");
		// 调用bootstrap样式
		pre.className = "text-" + flag;
		pre.innerHTML = data;
		output.appendChild(pre);
	}

	window.addEventListener("load", init, false);
	window.addEventListener("unload", dispose, false);
</script>
</html>

源码地址:https://github.com/XuePeng87/websocketapp

© 著作权归作者所有

巧乐兹
粉丝 2
博文 17
码字总数 19978
作品 0
北京
私信 提问
2017-03-24日志

1.不同角色菜单部分重构 2.websocket部分流程梳理,代码搭建测试 3.跟中源沟通线上注册会员卡的功能的页面设计流程方面的内容 4.跟同事沟通接口方面的细节内容 5.调用mysql的自定义函数时需要...

test2013
2017/03/24
1
0
spring boot websocket stomp 实现广播通信和一对一通信聊天

一、前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信。刚接触java寻找先关替代品,发现 java 体系中有一套基于stomp协议的websocket通信的框...

ejiyuan
2018/07/11
0
0
Java 会比 Go 长寿?编程语言的生命周期要如何判断

预测编程语言的生命周期是非常棘手的事情。1995 年发布的 Java ,到现在依然坚挺,之前有些预测 Java 结局的都很尴尬,而有些新兴语言却只是昙花一现。到底该怎么来判断编程语言的生命周期呢...

王练
2017/09/02
4.5K
16
WebSocket 实战之——【WebSocket 原理】

一、WebSocket是什么? HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)。 首先HTTP有1.1和1.0之说,也就是所谓的kee...

tinywan1227
2016/09/21
0
0
为什么 Linux 用户应该试一试 Rust

在 Linux 系统上安装 Rust 编程语言可能是你近年来所做的最有价值的事情之一。 Rust 是一种相当年轻和现代的编程语言,具有许多使其非常灵活而及其安全的功能。数据显示它正在变得非常受欢迎...

作者: Sandra Henry-stocker
2018/10/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

浅析大数据 学习大数据后能做什么

大数据时代的到来使得大数据开发人才迎来了前所未有的机遇和挑战!一个绝佳的入行机会摆在了众人面前!于是,很多人都在打听,大数据到底有何应用?可以用来做什么?好程序员今天就为大家作出...

好程序员IT
18分钟前
1
0
C# USB视频人脸检测

此程序基于 虹软人脸识别进行的开发 SDK下载地址:https://ai.arcsoft.com.cn/ucenter/user/reg?utm_source=csdn1&utm_medium=referral 前提条件 从虹软官网下载获取ArcFace引擎应用开发包,...

是哇兴哥棒棒哒
29分钟前
2
0
Vagrant虚拟机硬盘扩容

# 停止虚拟机vagrant halt <machine_name># 进入VirtualBox VMs目录,查看并记录原磁盘uuid,留作后用vboxmanage showhdinfo box-disk1.vmdk# 克隆磁盘,vmdk格式无法调整大小,需要...

sskill
31分钟前
1
0
分布式商业萌芽,银行迎来发展新机遇

01 分布式商业萌芽,银行迎来发展新机遇 金融界:近几年区块链的热度经历了过山车般的转折。目前追逐区块链的资本也开始冷静下来,于此同时,各大商业银行对区块链的研究应用也越来越多。您认...

Java领航员
36分钟前
3
0
Spring系列教程六: Spring jdbcTemplate在Dao中的使用

概念 Spring中的jdbcTemplate的主要作用是实现数据的交互,下面我们就在dao层中如何使用jdbctemplate写测试案例 项目目录如下 基于xml实现jdbctemplate 这里我们使用的是JdbcDaoSupport这个类...

我叫小糖主
40分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部