maven netty 配置_springboot2.3手册:5分钟用Netty搭建高性能异步WebSocket服务
互聯(lián)網(wǎng)應用架構:專注編程教學,架構,JAVA,Python,微服務,機器學習等領域,歡迎關注,一起學習。
斷更快兩個月了,6月份工作忙到飛起,7月份家里又有事,已經(jīng)累到躺下就想睡覺的程度了。
現(xiàn)在我們做WebSocket服務,很多時候都是會整合Netty作為服務器,但是有個問題,就是發(fā)現(xiàn)網(wǎng)上的整合起來,比較繁瑣,各種配置,各種對應,最關鍵是千篇一律的網(wǎng)文,看得好辛苦了,今天咱們來介紹一個開源的組件,幫你快速搭建基于Netty的WebSocket服務,讓你更加輕松,更加專注于業(yè)務開發(fā)。
組件介紹
netty-websocket-spring-boot-starter是基于Netty服務器來做的WebSocket服務器,不需要配置Netty服務器信息,只需要配置Webscoket的注解就行,目前用起來還是很方便的。
加載包體
<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.bootsgroupId>
<artifactId>bootsartifactId>
<version>1.1.0.RELEASEversion>
parent>
<groupId>boots.weboscketgroupId>
<artifactId>boots-weboscketartifactId>
<version>2.0.0.RELEASEversion>
<name>boots-weboscketname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>com.bootsgroupId>
<artifactId>module-boots-apiartifactId>
<version>2.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>io.nettygroupId>
<artifactId>netty-allartifactId>
dependency>
<dependency>
<groupId>org.yeautygroupId>
<artifactId>netty-websocket-spring-boot-starterartifactId>
<version>0.9.5version>
dependency>
dependencies>
project>
配置文件
######配置基本信息########配置應用名稱spring.application.name: boots-websocket
##配置時間格式,為了避免精度丟失,全部換成字符串spring.jackson.timeZone: GMT+8
spring.jackson.dateFormat: yyyy-MM-dd HH:mm:ss
spring.jackson.generator.writeNumbersAsStrings: true
單個推送后端代碼
/*** All rights Reserved, Designed By 林溪
* Copyright: Copyright(C) 2016-2020
* Company 溪云閣 .
*/
package com.boots.websocket.websocket;
import org.yeauty.annotation.OnClose;
import org.yeauty.annotation.OnError;
import org.yeauty.annotation.OnMessage;
import org.yeauty.annotation.OnOpen;
import org.yeauty.annotation.ServerEndpoint;
import org.yeauty.pojo.Session;
import com.module.boots.exception.CommonRuntimeException;
import io.netty.handler.codec.http.HttpHeaders;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
/**
* 單個推送服務
* @author:溪云閣
* @date:2020年8月4日
*/
@Slf4j
@ServerEndpoint(path = "/SingleSocket", host = "127.0.0.1", port = "8900")
public class SingleSocket { /**
* 新建WebSocket的時候,執(zhí)行該方法
* @author 溪云閣
* @param session
* @param headers void
*/
@OnOpen
@SneakyThrows(CommonRuntimeException.class) public void onOpen(Session session, HttpHeaders headers) { log.info("WebSocket服務連接成功");
} /**
* 關閉WebSocket的時候,執(zhí)行該方法
* @author 溪云閣
* @param session void
*/
@OnClose
@SneakyThrows(CommonRuntimeException.class) public void onClose(Session session) { log.info("WebSocket服務關閉成功");
} /**
* WebSocket發(fā)生異常的時候,執(zhí)行該方法
* @author 溪云閣
* @param session
* @param th void
*/
@OnError
public void onError(Session session, Throwable th) { log.error("{}", th.fillInStackTrace());
th.printStackTrace();
} /**
* WebSocket接收到的消息為字符串的時候,指定該方法
* @author 溪云閣
* @param session
* @param msg void
*/
@OnMessage
@SneakyThrows(CommonRuntimeException.class) public void OnMessage(Session session, String msg) { log.info("接收到的信息:{}", msg);
session.sendText(msg);
}}
單個推送前端頁面
span style="-webkit-tap-highlight-color: transparent;box-sizing: border-box;border-width: 0px;border-style: initial;border-color: initial;">html><html>
<head>
<meta charset="utf-8">
<title>單個推送title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/layui/css/layui.css" media="all">
head>
<body>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px; margin-left: 310px; margin-right: 310px">
<legend>輸出內(nèi)容legend>
fieldset>
<form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px">
<div class="layui-form-item layui-form-text">
<div class="layui-input-block">
<textarea placeholder="請輸入內(nèi)容" class="layui-textarea" rows="20" id="contentArea">textarea>
div>
div>
form>
<form class="layui-form layui-form-pane" style="margin-left: 310px; margin-right: 310px" action="">
<div class="layui-form-item">
<label class="layui-form-label">輸入label>
<div class="layui-input-block">
<input type="text" name="content" id="content" autocomplete="off" placeholder="請輸入內(nèi)容" class="layui-input">
div>
div>
form>
<div class="layui-form-item" style="margin-left: 310px; margin-right: 310px">
<button class="layui-btn" onclick="sendMsg()">發(fā)送button>
div>
<script src="/js/jquery.min.js" >script>
<script src="/layui/layui.js" charset="utf-8">script>
<script>
var websocket = new WebSocket("ws://127.0.0.1:8900/SingleSocket");
//WebSocket打開
websocket.onopen = function(evt) {
$('#contentArea').html("WebSocket服務連接成功");
};
//WebSocket推送
websocket.onmessage = function(evt) {
var val = $('#contentArea').val() + "
";
$('#contentArea').html(val + evt.data);
};
//WebSocket關閉
websocket.onclose = function(evt) {
$('#contentArea').html("WebSocket服務關閉成功");
};
function sendMsg() {
var text = $('#content').val();
websocket.send(text);
}
script>
body>
html>
群發(fā)推送后端代碼
/*** All rights Reserved, Designed By 林溪
* Copyright: Copyright(C) 2016-2020
* Company 溪云閣 .
*/
package com.boots.websocket.websocket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.yeauty.annotation.OnClose;
import org.yeauty.annotation.OnError;
import org.yeauty.annotation.OnMessage;
import org.yeauty.annotation.OnOpen;
import org.yeauty.annotation.ServerEndpoint;
import org.yeauty.pojo.Session;
import com.module.boots.exception.CommonRuntimeException;
import io.netty.handler.codec.http.HttpHeaders;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
/**
* 群組推送服務
* @author:溪云閣
* @date:2020年8月4日
*/
@Slf4j
@ServerEndpoint(path = "/groupSocket", host = "127.0.0.1", port = "8901")
public class GroupSocket {
// 定義存放Session的緩存對象
private Map map = new ConcurrentHashMap<>();
/**
* 新建WebSocket的時候,執(zhí)行該方法
* @author 溪云閣
* @param session
* @param headers void
*/
@OnOpen
@SneakyThrows(CommonRuntimeException.class)
public void onOpen(Session session, HttpHeaders headers) {
// 把Session放到緩存中,后面群發(fā)使用
map.put(session.id().toString(), session);
log.info("WebSocket服務連接成功");
}
/**
* 關閉WebSocket的時候,執(zhí)行該方法
* @author 溪云閣
* @param session void
*/
@OnClose
@SneakyThrows(CommonRuntimeException.class)
public void onClose(Session session) {
// 當關閉的時候,刪除緩存中的session
if (map.containsKey(session.id().toString())) {
map.remove(session.id().toString());
}
log.info("WebSocket服務關閉成功");
}
/**
* WebSocket發(fā)生異常的時候,執(zhí)行該方法
* @author 溪云閣
* @param session
* @param th void
*/
@OnError
public void onError(Session session, Throwable th) {
log.error("{}", th.fillInStackTrace());
th.printStackTrace();
}
/**
* WebSocket接收到的消息為字符串的時候,指定該方法
* @author 溪云閣
* @param session
* @param msg void
*/
@OnMessage
@SneakyThrows(CommonRuntimeException.class)
public void OnMessage(String msg) {
map.forEach((key, session) -> {
log.info("接收到的信息:{}", msg);
session.sendText(msg);
});
}
}
群發(fā)推送前端頁面
span style="-webkit-tap-highlight-color: transparent;box-sizing: border-box;border-width: 0px;border-style: initial;border-color: initial;">html><html>
<head>
<meta charset="utf-8">
<title>群發(fā)推送title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/layui/css/layui.css" media="all">
head>
<body>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px; margin-left: 310px; margin-right: 310px">
<legend>輸出內(nèi)容legend>
fieldset>
<form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px">
<div class="layui-form-item layui-form-text">
<div class="layui-input-block">
<textarea placeholder="請輸入內(nèi)容" class="layui-textarea" rows="10" id="contentArea1">textarea>
div>
div>
form>
<form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px">
<div class="layui-form-item layui-form-text">
<div class="layui-input-block">
<textarea placeholder="請輸入內(nèi)容" class="layui-textarea" rows="10" id="contentArea2">textarea>
div>
div>
form>
<form class="layui-form layui-form-pane" style="margin-left: 310px; margin-right: 310px" action="">
<div class="layui-form-item">
<label class="layui-form-label">輸入label>
<div class="layui-input-block">
<input type="text" name="content" id="content" autocomplete="off" placeholder="請輸入內(nèi)容" class="layui-input">
div>
div>
form>
<div class="layui-form-item" style="margin-left: 310px; margin-right: 310px">
<button class="layui-btn" onclick="sendMsg()">發(fā)送button>
div>
<script src="/js/jquery.min.js" >script>
<script src="/layui/layui.js" charset="utf-8">script>
<script>
var websocket1 = new WebSocket("ws://127.0.0.1:8901/groupSocket");
var websocket2 = new WebSocket("ws://127.0.0.1:8901/groupSocket");
//第一個WebSocket打開
websocket1.onopen = function(evt) {
$('#contentArea1').html("第一個WebSocket服務連接成功");
};
//第一個WebSocket推送
websocket1.onmessage = function(evt) {
var val = $('#contentArea1').val() + "
";
$('#contentArea1').html(val + evt.data);
};
//第一個WebSocket關閉
websocket1.onclose = function(evt) {
$('#contentArea1').html("第一個WebSocket服務關閉成功");
};
//第二個WebSocket打開
websocket2.onopen = function(evt) {
$('#contentArea2').html("第二個WebSocket服務連接成功");
};
//第二個WebSocket推送
websocket2.onmessage = function(evt) {
var val = $('#contentArea2').val() + "
";
$('#contentArea2').html(val + evt.data);
};
//第二個WebSocket關閉
websocket2.onclose = function(evt) {
$('#contentArea2').html("第二個WebSocket服務關閉成功");
};
function sendMsg() {
var text = $('#content').val();
websocket1.send(text);
websocket2.send(text);
}
script>
body>
html>
啟動類
package com.boots.websocket;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* 服務啟動類
* @author:溪云閣
* @date:2020年5月2日
*/
@SpringBootApplication
@ComponentScan(basePackages = { "com.module", "com.boots" })
public class BootsWebSocketApplication {
public static void main(String[] args) {
SpringApplication.run(BootsWebSocketApplication.class, args);
}}
單個推送測試
群發(fā)推送測試
總結及拓展
相比于需要自己整合Netty的配置,目前用起來還是很方便的,Netty的配置可以在注解類ServerEndpoint看到,里面一進去就會發(fā)現(xiàn)還是很清楚的。
目前發(fā)現(xiàn)有個不足的,就是超過一定時間不連接的時候,就會自動斷開,不過這個可以在前端做個超時設置或者心跳檢測,就可以了,問題不大,用起來還是很爽的。
--END--
總結
以上是生活随笔為你收集整理的maven netty 配置_springboot2.3手册:5分钟用Netty搭建高性能异步WebSocket服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea加入springboot插件_带
- 下一篇: lottie插件_RN常用插件集