Java中Spring WebSocket详解

2025-05-29 0 70

首先 pom.xml

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.8.RELEASE</version>

</parent>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-io</artifactId>

</dependency>

<dependency>

<groupId>javax.websocket</groupId>

<artifactId>javax.websocket-api</artifactId>

<version>1.0</version>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-websocket</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

<exclusions>

<exclusion>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-tomcat</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-undertow</artifactId>

</dependency>

接收消息后的处理类 GameHandler :

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74
import java.net.URI;

import org.springframework.web.socket.BinaryMessage;

import org.springframework.web.socket.CloseStatus;

import org.springframework.web.socket.PongMessage;

import org.springframework.web.socket.TextMessage;

import org.springframework.web.socket.WebSocketSession;

import org.springframework.web.socket.handler.AbstractWebSocketHandler;

public class GameHandler extends AbstractWebSocketHandler {

/**

* 处理字符串类的信息

*

* @param session

* @param message

* @throws Exception

*/

@Override

protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

session.sendMessage(new TextMessage(message.asBytes()));

}

/**

* 处理二进制类的信息

*

* @param session

* @param message

* @throws Exception

*/

@Override

protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {

session.sendMessage(new BinaryMessage(message.getPayload()));

}

/**

* ping-pong

*

* @param session

* @param message

* @throws Exception

*/

@Override

protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {

}

/**

* 传出错误的处理

*

* @param session

* @param exception

* @throws Exception

*/

@Override

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

}

/**

* 连接关闭的处理

*

* @param session

* @param status

* @throws Exception

*/

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

}

/**

* 连接建立后的处理

*

* @param session

* @throws Exception

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

}

}

握手信息拦截器 WebSocketHandshakeInterceptor :

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
import java.util.Map;

import javax.servlet.http.Cookie;

import org.springframework.http.server.ServerHttpRequest;

import org.springframework.http.server.ServerHttpResponse;

import org.springframework.http.server.ServletServerHttpRequest;

import org.springframework.web.socket.WebSocketHandler;

import org.springframework.web.socket.server.HandshakeInterceptor;

public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {

@Override

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse shr1, WebSocketHandler wsh, Map<String, Object> attributes) throws Exception {

// 此处可以做一些权限认证的事情或者其他

return true;

}

@Override

public void afterHandshake(ServerHttpRequest shr, ServerHttpResponse shr1, WebSocketHandler wsh, Exception excptn) {

}

}

使用WebSocket的配置类 WebSocketConfig :

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.config.annotation.WebSocketConfigurer;

import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration

@EnableWebSocket

public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

// 允许连接的域,只能以http或https开头

String[] allowsOrigins = {"http://127.0.0.1:1213", "http://localhost:1213"};

registry.addHandler(gameHandler(),"/game").addInterceptors(handshakeInterceptor()).setAllowedOrigins(allowsOrigins);

}

@Bean

public GameHandler gameHandler() {

return new GameHandler();

}

@Bean

public WebSocketHandshakeInterceptor handshakeInterceptor() {

return new WebSocketHandshakeInterceptor();

}

}

启动类 Launcher :

?

1

2

3

4

5

6
@SpringBootApplication

public class Launcher {

public static void main(String[] params) {

SpringApplication.run(Launcher.class, params);

}

}

配置文件 main/resources/application.properties:

?

1

2

3

4

5

6

7
server.port=1213

server.session-timeout=1800

server.undertow.io-threads=4

server.undertow.worker-threads=20

server.undertow.buffer-size=1024

server.undertow.buffers-per-region=1024

server.undertow.direct-buffers=true

前端的测试页面 main\\resources\\static\\index.html

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163
<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Platform Gateway</title>

<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">

<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="external nofollow" rel="stylesheet">-->

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>

<script src="https://cdn.bootcss.com/jquery-scrollTo/2.1.2/jquery.scrollTo.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.6/pako.min.js"></script>

<!--[if lt IE 9]>

<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>

<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>

<![endif]-->

<style>

#message{

height: 600px;

overflow-y:auto;

}

</style>

</head>

<body>

<div class="container">

<h1>WebSocket Test Page</h1>

<hr/>

<div class="form-inline">

<div class="form-group">

<label for="wsAddr">WebSocket Address: </label>

<div class="input-group">

<span class="input-group-addon" id="basic-ws">ws://127.0.0.1:1213/</span>

<input type="text" class="form-control" id="basic-ws-addr" aria-describedby="basic-ws" placeholder="game" data-container="body" data-placement="top" data-content="链接地址不能为空,请填写">

</div>

</div>

<button type="button" id="btnConnect" class="btn btn-primary" onclick="connect();">

<span class="glyphicon glyphicon-resize-small" aria-hidden="true"></span>

连接

</button>

<button type="button" id="btnClose" class="btn btn-danger" disabled="disabled" onclick="closeWebSocket();">

<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>

断开

</button>

<button type="button" id="btnSend" class="btn btn-info" disabled="disabled" style="margin-left: 50px;" onclick="send();">

<span class="glyphicon glyphicon-transfer" aria-hidden="true"></span>

发送消息

</button>

</div><br/>

<textarea class="form-control" id="inMsg" rows="5" placeholder="在这里输入需要发送的信息..."></textarea>

<hr/>

<div id="message"></div>

</div>

<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script type="text/javascript">

function zip(str) {

var binaryString = pako.gzip(str, {to: 'string'});

return btoa(binaryString);

}

function unzip(b64Data) {

var strData = atob(b64Data);

var charData = strData.split('').map(function (x) {

return x.charCodeAt(0);

});

var binData = new Uint8Array(charData);

var data = pako.inflate(binData);

strData = String.fromCharCode.apply(null, new Uint16Array(data));

return strData;

}

var websocket = null;

var wsBaseUrl = null;

var wsUrl = null;

function init() {

wsBaseUrl = "ws://" + window.location.host + "/";

$("#basic-ws").text(wsBaseUrl);

$(function () {

$('[data-toggle="popover"]').popover();

});

return false;

}

//关闭WebSocket连接

function closeWebSocket() {

if (websocket) {

websocket.close();

}

return false;

}

//将消息显示在网页上

function setMessageInnerHTML(who, msg) {

var message = null;

if (who === 1) {

message = '<div class="alert alert-success" role="alert">本地: ' + msg + '</div>';

} else {

message = '<div class="alert alert-info" role="alert">服务器: ' + msg + '</div>';

}

document.getElementById('message').innerHTML = (document.getElementById('message').innerHTML + message);

$("#message").scrollTo('100%');

return false;

}

//发送消息

function send() {

if (websocket) {

var message = $("#inMsg").val();

websocket.send(zip(message));

setMessageInnerHTML(1, message);

}

return false;

}

function connect() {

var url = $("#basic-ws-addr").val();

if (url.length <= 0) {

$('#basic-ws-addr').popover('show');

setTimeout(function () {

$('#basic-ws-addr').popover('hide');

}, 3000);

} else {

wsUrl = wsBaseUrl + url;

if ('WebSocket' in window) {

websocket = new WebSocket(wsUrl);

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

websocket.onerror = function () {

setMessageInnerHTML(0, "WebSocket连接发生错误 -> " + wsUrl);

$("#btnConnect").removeAttr("disabled");

$("#btnClose").attr("disabled", "disabled");

$("#btnSend").attr("disabled", "disabled");

};

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

websocket.onopen = function () {

setMessageInnerHTML(0, "WebSocket连接成功 -> " + wsUrl);

$("#btnConnect").attr("disabled", "disabled");

$("#btnClose").removeAttr("disabled");

$("#btnSend").removeAttr("disabled");

};

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

websocket.onmessage = function (event) {

setMessageInnerHTML(0, unzip(event.data));

};

//连接关闭的回调方法

websocket.onclose = function () {

setMessageInnerHTML(0, "WebSocket连接关闭 -> " + wsUrl);

$("#btnConnect").removeAttr("disabled");

$("#btnClose").attr("disabled", "disabled");

$("#btnSend").attr("disabled", "disabled");

};

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

window.onbeforeunload = function () {

closeWebSocket();

};

} else {

alert('Not support websocket');

}

}

return false;

}

window.onload = init();

</script>

</body>

</html>

到此就可以使用 WebSocket 进行前后端的通信了,如果大家还有不明白的或者有更好的方法,可以在下方的留言区讨论。

原文链接:https://my.oschina.net/Kxvz/blog/1591764

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java中Spring WebSocket详解 https://www.kuaiidc.com/112984.html

相关文章

发表评论
暂无评论