websocket接口调用(websocket接口开发)

http://www.itjxue.com  2023-01-27 19:32  来源:未知  点击次数: 

如何使用WebSocket

在pom.xml中添加Jar包依赖

1 dependency

2 groupIdjavax/groupId

3 artifactIdjavaee-api/artifactId

4 version7.0/version

5 scopeprovided/scope

6 /dependency

客户端(Web主页)代码:

1 %@ page language="java" pageEncoding="UTF-8" %

2 !DOCTYPE html

3 html

4 head

5 titleJava后端WebSocket的Tomcat实现/title

6 /head

7 body

8 Welcomebr/input id="text" type="text"/

9 button onclick="send()"发送消息/button

10 hr/

11 button onclick="closeWebSocket()"关闭WebSocket连接/button

12 hr/

13 div id="message"/div

14 /body

15

16 script type="text/javascript"

17 var websocket = null;

18 //判断当前浏览器是否支持WebSocket

19 if ('WebSocket' in window) {

20 websocket = new WebSocket("ws://localhost:8080/websocket");

21 }

22 else {

23 alert('当前浏览器 Not support websocket')

24 }

25

26 //连接发生错误的回调方法

27 websocket.onerror = function () {

28 setMessageInnerHTML("WebSocket连接发生错误");

29 };

30

31 //连接成功建立的回调方法

32 websocket.onopen = function () {

33 setMessageInnerHTML("WebSocket连接成功");

34 }

35

36 //接收到消息的回调方法

37 websocket.onmessage = function (event) {

38 setMessageInnerHTML(event.data);

39 }

40

41 //连接关闭的回调方法

42 websocket.onclose = function () {

43 setMessageInnerHTML("WebSocket连接关闭");

44 }

45

46 //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。

47 window.onbeforeunload = function () {

48 closeWebSocket();

49 }

50

51 //将消息显示在网页

52 function setMessageInnerHTML(innerHTML) {

53 document.getElementById('message').innerHTML += innerHTML + 'br/';

54 }

55

56 //关闭WebSocket连接

57 function closeWebSocket() {

58 websocket.close();

59 }

60

61 //发送消息

62 function send() {

63 var message = document.getElementById('text').value;

64 websocket.send(message);

65 }

66 /script

67 /html

Java Web后端代码

1 package me.gacl.websocket;

2

3 import java.io.IOException;

4 import java.util.concurrent.CopyOnWriteArraySet;

5

6 import javax.websocket.*;

7 import javax.websocket.server.ServerEndpoint;

8

9 /**

10 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,

11 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端

12 */

13 @ServerEndpoint("/websocket")

14 public class WebSocketTest {

15 //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。

16 private static int onlineCount = 0;

17

18 //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识

19 private static CopyOnWriteArraySetWebSocketTest webSocketSet = new CopyOnWriteArraySetWebSocketTest();

20

21 //与某个客户端的连接会话,需要通过它来给客户端发送数据

22 private Session session;

23

24 /**

25 * 连接建立成功调用的方法

26 * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据

27 */

28 @OnOpen

29 public void onOpen(Session session){

30 this.session = session;

31 webSocketSet.add(this); //加入set中

32 addOnlineCount(); //在线数加1

33 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());

34 }

35

36 /**

37 * 连接关闭调用的方法

38 */

39 @OnClose

40 public void onClose(){

41 webSocketSet.remove(this); //从set中删除

42 subOnlineCount(); //在线数减1

43 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());

44 }

45

46 /**

47 * 收到客户端消息后调用的方法

48 * @param message 客户端发送过来的消息

49 * @param session 可选的参数

50 */

51 @OnMessage

52 public void onMessage(String message, Session session) {

53 System.out.println("来自客户端的消息:" + message);

54 //群发消息

55 for(WebSocketTest item: webSocketSet){

56 try {

57 item.sendMessage(message);

58 } catch (IOException e) {

59 e.printStackTrace();

60 continue;

61 }

62 }

63 }

64

65 /**

66 * 发生错误时调用

67 * @param session

68 * @param error

69 */

70 @OnError

71 public void onError(Session session, Throwable error){

72 System.out.println("发生错误");

73 error.printStackTrace();

74 }

75

76 /**

77 * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。

78 * @param message

79 * @throws IOException

80 */

81 public void sendMessage(String message) throws IOException{

82 this.session.getBasicRemote().sendText(message);

83 //this.session.getAsyncRemote().sendText(message);

84 }

85

86 public static synchronized int getOnlineCount() {

87 return onlineCount;

88 }

89

90 public static synchronized void addOnlineCount() {

91 WebSocketTest.onlineCount++;

92 }

93

94 public static synchronized void subOnlineCount() {

95 WebSocketTest.onlineCount--;

96 }

97 }

WebSocket入门及使用指南

在浏览器与服务器通信间,传统的 HTTP 请求在某些场景下并不理想,比如实时聊天、实时性的小游戏等等,

其面临主要两个缺点:

其基于 HTTP 的主要解决方案有:

可以看到,基于 HTTP 协议的方案都包含一个本质缺陷 —— 「被动性」,服务端无法下推消息,仅能由客户端发起请求不断询问是否有新的消息,同时对于客户端与服务端都存在性能消耗。

WebSocket 是 HTML5 中提出的新的网络协议标准,其包含几个特点:

在浏览器中使用 Websocket 非常简单,在支持 Websocket 的浏览器中会提供了原生的 WebSocekt 对象,其中对于消息的接收与数据帧处理在浏览器中已经封装好了。

以下将用一个简单的例子解释如何使用 WebSocekt;

浏览器中提供了原生类 WebSocket ,使用 new 关键字实例化它:

接收两个参数:

WebSocket 类提供了一些常量表示连接状态:

实例化对象中可以监听到以下事件:

首先触发 open 事件,之后每次发送数据服务端都会回复数据,因此触发了 message 事件,如果触发 close 事件;这里最后一次发送之后未收到服务端回复也是因为客户端立即断开了连接;websocket.send()是发送信息方法

对 WebSocket 实例监听事件有两种方式,这里以 message 事件为例:

在 message 回调函数中得到 MessageEvent 类型参数 e ,我们需要的数据可以通过 e.data 获取;

需要注意的一点是:不论服务端与客户端,其接受到的数据都是序列化后的字符串(当然也有 ArrayBuffer|Blob 类型数据),很多时候我们需要解析处理数据,比如 JSON.parse(e.data) ;

由于网络环境复杂,某些情况会出现断开连接或者连接出错,需要我们在 close 或者 error 事件中监听非正常断开并重连;

由于一些原因在 error 时浏览器并不会响应回调事件,因此稳妥的做法还需要在 open 之后开启一个定时任务去判断当前的连接状态 readyState ,在出现异常情况下尝试重连;

websocket规范定义了心跳机制,一方可以通过发送ping(opcode 0x9)消息给另一方,另一方收到ping后应该尽可能快的返回pong(0xA)。

心跳机制是用于检测连接的对方在线状态,因此如果没有心跳,那么无法判断一方还在连接状态中,一些网络层比如 nginx 或者浏览器层会主动断开连接,

在 JavaScript 中,WebSocket 并没有开放 ping/pong 的 API ,虽然浏览器自带了心跳处理,然而不同厂商的实现也不尽相同,因此需要在我们开发时候与服务端约定好一个自实现的心跳机制;

比如浏览器中,检测到 open 事件后,启动一个定时任务,每次发送数据 0x9 给服务端,而服务端返回 0xA 作为响应;

实践下来,心跳的定时任务一般是相隔 15-20 秒发送一次。

前文说到,Websocket 是建立与 TCP 之上,那么其与 HTTP 协议有和关系呢?

Websocket 连接分为建连阶段与连接阶段,在建立连接阶段借助于 HTTP ,而在连接阶段则与 HTTP 无关。

从浏览器的 Network 中,找到 ws 连接,可以看到:

这是一个标准的 HTTP 请求,相比于我们常见的 HTTP 请求协议,请求头中多了几个字段:

重点请求首部意义如下:

响应头中:

可以看到其返回状态码为 101 ,表示切换协议;

Upgrade 与 Connection 用于回复客户端表示已经切换协议成功;

Sec-WebSocket-Accept 字段与 Sec-WebSocket-Key 相对应,用于验证服务的正确性;

当通过 HTTP 建立连接握手后,接下来则是真正的 Websocket 连接了,其基于 TCP 收发数据,Websocket 封装并开放接口。

在 HTTP 协议中,很多时候为了加密与安全需要使用 HTTPS 请求(HTTP + TCL);

相应的,在 Websocket 协议中,也是可以使用加密传输的 —— wss ,比如 wss://localhost:8080 。

使用的也是与 HTTPS 一样的证书,在这里一般是交由 Nginx 等服务层去做证书处理。

本文参考文章:

前端怎么调用socket

!DOCTYPE?html??

meta?charset="utf-8"?/??

titleWebSocket?Test/title??

script?language="javascript"type="text/javascript"??

????var?wsUri?="ws://echo.websocket.org/";?

????var?output;??

????

????function?init()?{?

????????output?=?document.getElementById("output");?

????????testWebSocket();?

????}??

?

????function?testWebSocket()?{?

????????websocket?=?new?WebSocket(wsUri);?

????????websocket.onopen?=?function(evt)?{?

????????????onOpen(evt)?

????????};?

????????websocket.onclose?=?function(evt)?{?

????????????onClose(evt)?

????????};?

????????websocket.onmessage?=?function(evt)?{?

????????????onMessage(evt)?

????????};?

????????websocket.onerror?=?function(evt)?{?

????????????onError(evt)?

????????};?

????}??

?

????function?onOpen(evt)?{?

????????writeToScreen("CONNECTED");?

????????doSend("WebSocket?rocks");?

????}??

?

????function?onClose(evt)?{?

????????writeToScreen("DISCONNECTED");?

????}??

?

????function?onMessage(evt)?{?

????????writeToScreen('span?style="color:?blue;"RESPONSE:?'+?evt.data+'/span');?

????????websocket.close();?

????}??

?

????function?onError(evt)?{?

????????writeToScreen('span?style="color:?red;"ERROR:/span?'+?evt.data);?

????}??

?

????function?doSend(message)?{?

????????writeToScreen("SENT:?"?+?message);??

????????websocket.send(message);?

????}??

?

????function?writeToScreen(message)?{?

????????var?pre?=?document.createElement("p");?

????????pre.style.wordWrap?=?"break-word";?

????????pre.innerHTML?=?message;?

????????output.appendChild(pre);?

????}??

?

????window.addEventListener("load",?init,?false);??

/script??

h2WebSocket?Test/h2??

div?id="output"/div??

/html

主要代码解读:

申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。。

var?wsUri?="ws://echo.websocket.org/";

websocket?=?new?WebSocket(wsUri);

WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,

我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。

当Browser和WebSocketServer连接成功后,会触发onopen消息;

websocket.onopen?=?function(evt)?{

};

如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;

websocket.onerror?=?function(evt)?{

};

当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;

websocket.onmessage?=?function(evt)?{

};

当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。

websocket.onclose?=?function(evt)?{

};

WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。

WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

如何测试webservice和websocket接口

您好:WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chrome12就已经开始支持,随着协议草案的不断变化,各个浏览器对协议的实现也在不停的更新。该协议还是草案,没有成为标准,不过成为标准应该只是时间问题了,从WebSocket草案的提出到现在已经有十几个版本了,目前最新的是版本17,所对应的协议版本号为13,目前对该协议支持最完善的浏览器应该是chrome,毕竟WebSocket协议草案也是Google发布的。

1. WebSocket API简介

首先看一段简单的javascript代码,该代码调用了WebSockets的API。

[javascript] view plaincopy

var ws = new WebSocket(“ws://echo.websocket.org”);

ws.onopen = function(){ws.send(“Test!”); };

ws.onmessage = function(evt){console.log(evt.data);ws.close();};

ws.onclose = function(evt){console.log(“WebSocketClosed!”);};

ws.onerror = function(evt){console.log(“WebSocketError!”);};

这份代码总共只有5行,现在简单概述一下这5行代码的意义。

第一行代码是在申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,当Browser和WebSocketServer连接成功后,会触发onopen消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。

(责任编辑:IT教学网)

更多

推荐导航代码文章