{"id":19476090,"url":"https://github.com/hwywl/netty-websocket-spring-boot","last_synced_at":"2025-11-01T00:02:57.165Z","repository":{"id":88797470,"uuid":"151942442","full_name":"HWYWL/netty-websocket-spring-boot","owner":"HWYWL","description":"netty-websocket之路","archived":false,"fork":false,"pushed_at":"2024-05-16T17:14:59.000Z","size":92,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T08:59:37.230Z","etag":null,"topics":["netty","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HWYWL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-07T13:07:56.000Z","updated_at":"2019-04-27T05:52:57.000Z","dependencies_parsed_at":"2025-01-08T06:32:41.353Z","dependency_job_id":"70d247cf-28a2-4a3f-850e-423a116ad3d3","html_url":"https://github.com/HWYWL/netty-websocket-spring-boot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HWYWL%2Fnetty-websocket-spring-boot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HWYWL%2Fnetty-websocket-spring-boot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HWYWL%2Fnetty-websocket-spring-boot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HWYWL%2Fnetty-websocket-spring-boot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HWYWL","download_url":"https://codeload.github.com/HWYWL/netty-websocket-spring-boot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249040041,"owners_count":21202813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["netty","websocket"],"created_at":"2024-11-10T19:36:25.578Z","updated_at":"2025-11-01T00:02:57.158Z","avatar_url":"https://github.com/HWYWL.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# netty-websocket-spring-boot\nnetty-websocket之路\n\n### 说明\n- jdk版本为1.8或1.8+\n- spring-boot版本为2.0.0.RELEASE或以上\n\n\n### 快速开始\n\n- 添加依赖:\n\n```xml\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003eorg.yeauty\u003c/groupId\u003e\n\t\t\u003cartifactId\u003enetty-websocket-spring-boot-starter\u003c/artifactId\u003e\n\t\t\u003cversion\u003e0.7.2\u003c/version\u003e\n\t\u003c/dependency\u003e\n```\n\n- new一个`ServerEndpointExporter`对象，交给Spring容器，表示要开启WebSocket功能，样例如下:\n\n```java\n@Configuration\npublic class WebSocketConfig {\n    @Bean\n    public ServerEndpointExporter serverEndpointExporter() {\n        return new ServerEndpointExporter();\n    }\n}\n```\n\n- 在端点类上加上`@ServerEndpoint`、`@Component`注解，并在相应的方法上加上`@OnOpen`、`@OnClose`、`@OnError`、`@OnMessage`、`@OnBinary`、`OnEvent`注解，样例如下：\n\n```java\n@ServerEndpoint\n@Component\npublic class WebSocketOneService {\n    /**\n     * 当有新的WebSocket连接进入时，对该方法进行回调 注入参数的类型:Session、HttpHeaders\n     * @param session\n     * @param headers\n     * @throws IOException\n     */\n    @OnOpen\n    public void onOpen(Session session, HttpHeaders headers) throws IOException {\n        System.out.println(\"新的WebSocket连接进入一号\");\n    }\n\n    /**\n     * 当有WebSocket连接关闭时，对该方法进行回调 注入参数的类型:Session\n     * @param session\n     * @throws IOException\n     */\n    @OnClose\n    public void onClose(Session session) throws IOException {\n        System.out.println(\"一号WebSocket连接关闭\");\n    }\n\n    /**\n     * 当有WebSocket抛出异常时，对该方法进行回调 注入参数的类型:Session、Throwable\n     * @param session\n     * @param throwable\n     */\n    @OnError\n    public void onError(Session session, Throwable throwable) {\n        throwable.printStackTrace();\n    }\n\n    /**\n     * 当接收到字符串消息时，对该方法进行回调 注入参数的类型:Session、String\n     * @param session\n     * @param message\n     */\n    @OnMessage\n    public void OnMessage(Session session, String message) {\n        System.out.println(message);\n        session.sendText(\"Hello Netty! ---\u003e \" + message);\n    }\n\n    /**\n     * 当接收到二进制消息时，对该方法进行回调 注入参数的类型:Session、byte[]\n     * @param session\n     * @param bytes\n     */\n    @OnBinary\n    public void OnBinary(Session session, byte[] bytes) {\n        for (byte b : bytes) {\n            System.out.println(b);\n        }\n        session.sendBinary(bytes);\n    }\n\n    /**\n     * 当接收到Netty的事件时，对该方法进行回调 注入参数的类型:Session、Object\n     * @param session\n     * @param evt\n     */\n    @OnEvent\n    public void onEvent(Session session, Object evt) {\n        if (evt instanceof IdleStateEvent) {\n            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;\n            switch (idleStateEvent.state()) {\n                case READER_IDLE:\n                    System.out.println(\"一号读操作空闲\");\n                    break;\n                case WRITER_IDLE:\n                    System.out.println(\"一号写操作空闲\");\n                    break;\n                case ALL_IDLE:\n                    System.out.println(\"一号所有操作空闲\");\n                    break;\n                default:\n                    break;\n            }\n        }\n    }\n}\n```\n\n- 打开WebSocket客户端，连接到`ws://127.0.0.1:80`\n\n\n### 注解\n###### @ServerEndpoint \n\u003e 当ServerEndpointExporter类通过Spring配置进行声明并被使用，它将会去扫描带有@ServerEndpoint注解的类\n\u003e 被注解的类将被注册成为一个WebSocket端点\n\u003e 所有的[配置项](#%E9%85%8D%E7%BD%AE)都在这个注解的属性中 ( 如:`@ServerEndpoint(\"/ws\")` )\n\n###### @OnOpen \n\u003e 当有新的WebSocket连接进入时，对该方法进行回调\n\u003e 注入参数的类型:Session、HttpHeaders\n\n###### @OnClose\n\u003e 当有WebSocket连接关闭时，对该方法进行回调\n\u003e 注入参数的类型:Session\n\n###### @OnError\n\u003e 当有WebSocket抛出异常时，对该方法进行回调\n\u003e 注入参数的类型:Session、Throwable\n\n###### @OnMessage\n\u003e 当接收到字符串消息时，对该方法进行回调\n\u003e 注入参数的类型:Session、String\n\n###### @OnBinary\n\u003e 当接收到二进制消息时，对该方法进行回调\n\u003e 注入参数的类型:Session、byte[]\n\n###### @OnEvent\n\u003e 当接收到Netty的事件时，对该方法进行回调\n\u003e 注入参数的类型:Session、Object\n\n### 配置\n\u003e 所有的配置项都在这个注解的属性中\n\n| 属性  | 默认值 | 说明 \n|---|---|---\n|path|\"/\"|WebSocket的path,也可以用`value`来设置\n|host|\"0.0.0.0\"|WebSocket的host,`\"0.0.0.0\"`即是所有本地地址\n|port|80|WebSocket绑定端口号。如果为0，则使用随机端口(端口获取可见 [多端点服务](#%E5%A4%9A%E7%AB%AF%E7%82%B9%E6%9C%8D%E5%8A%A1))\n|prefix|\"\"|当不为空时，即是使用application.properties进行配置，详情在 [通过application.properties进行配置](#%E9%80%9A%E8%BF%87APPLICATION.PROPERTIES%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE)\n|optionConnectTimeoutMillis|30000|与Netty的`ChannelOption.CONNECT_TIMEOUT_MILLIS`一致\n|optionSoBacklog|128|与Netty的`ChannelOption.SO_BACKLOG`一致\n|childOptionWriteSpinCount|16|与Netty的`ChannelOption.WRITE_SPIN_COUNT`一致\n|childOptionWriteBufferHighWaterMark|64*1024|与Netty的`ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK`一致,但实际上是使用`ChannelOption.WRITE_BUFFER_WATER_MARK`\n|childOptionWriteBufferLowWaterMark|32*1024|与Netty的`ChannelOption.WRITE_BUFFER_LOW_WATER_MARK`一致,但实际上是使用 `ChannelOption.WRITE_BUFFER_WATER_MARK`\n|childOptionSoRcvbuf|-1(即未设置)|与Netty的`ChannelOption.SO_RCVBUF`一致\n|childOptionSoSndbuf|-1(即未设置)|与Netty的`ChannelOption.SO_SNDBUF`一致\n|childOptionTcpNodelay|true|与Netty的`ChannelOption.TCP_NODELAY`一致\n|childOptionSoKeepalive|false|与Netty的`ChannelOption.SO_KEEPALIVE`一致\n|childOptionSoLinger|-1|与Netty的`ChannelOption.SO_LINGER`一致\n|childOptionAllowHalfClosure|false|与Netty的`ChannelOption.ALLOW_HALF_CLOSURE`一致\n|readerIdleTimeSeconds|0|与`IdleStateHandler`中的`readerIdleTimeSeconds`一致，并且当它不为0时，将在`pipeline`中添加`IdleStateHandler`\n|writerIdleTimeSeconds|0|与`IdleStateHandler`中的`writerIdleTimeSeconds`一致，并且当它不为0时，将在`pipeline`中添加`IdleStateHandler`\n|allIdleTimeSeconds|0|与`IdleStateHandler`中的`allIdleTimeSeconds`一致，并且当它不为0时，将在`pipeline`中添加`IdleStateHandler`\n\n### 通过application.properties进行配置\n\u003e 对注解中的`prefix`进行设置后，即可在`application.properties`中进行配置。如下：\n\n- 首先在ServerEndpoint注解中设置prefix的值\n```java\n@ServerEndpoint(prefix = \"netty.websocket.one.service\")\n@Component\npublic class WebSocketOneService {\n    ...\n}\n```\n- 接下来即可在`application.properties`中配置\n```\n\t# websocket一号配置\n\tnetty.websocket.one.service.host=0.0.0.0\n\tnetty.websocket.one.service.path=/\n\tnetty.websocket.one.service.port=80\n\t\n\t# websocket二号配置\n\tnetty.websocket.tow.service.host=0.0.0.0\n\tnetty.websocket.tow.service.path=/\n\tnetty.websocket.tow.service.port=8088\n```\n\n\u003e `application.properties`中的key与注解`@ServerEndpoint`中属性的对应关系如下:\n\n| 注解中的属性 | 配置文件中的key | 例子\n|---|---|---\n|path|{prefix}.path|netty-websocket.path\n|host|{prefix}.host|netty-websocket.host\n|port|{prefix}.port|netty-websocket.port\n|optionConnectTimeoutMillis|{prefix}.option.connect-timeout-millis|netty-websocket.option.connect-timeout-millis\n|optionSoBacklog|{prefix}.option.so-backlog|netty-websocket.option.so-backlog\n|childOptionWriteSpinCount|{prefix}.child-option.write-spin-count|netty-websocket.child-option.write-spin-count\n|childOptionWriteBufferHighWaterMark|{prefix}.child-option.write-buffer-high-water-mark|netty-websocket.child-option.write-buffer-high-water-mark\n|childOptionWriteBufferLowWaterMark|{prefix}.child-option.write-buffer-low-water-mark|netty-websocket.child-option.write-buffer-low-water-mark\n|childOptionSoRcvbuf|{prefix}.child-option.so-rcvbuf|netty-websocket.child-option.so-rcvbuf\n|childOptionSoSndbuf|{prefix}.child-option.so-sndbuf|netty-websocket.child-option.so-sndbuf\n|childOptionTcpNodelay|{prefix}.child-option.tcp-nodelay|netty-websocket.child-option.tcp-nodelay\n|childOptionSoKeepalive|{prefix}.child-option.so-keepalive|netty-websocket.child-option.so-keepalive\n|childOptionSoLinger|{prefix}.child-option.so-linger|netty-websocket.child-option.so-linger\n|childOptionAllowHalfClosure|{prefix}.child-option.allow-half-closure|netty-websocket.child-option.allow-half-closure\n|readerIdleTimeSeconds|{prefix}.reader-idle-time-seconds|netty-websocket.reader-idle-time-seconds\n|writerIdleTimeSeconds|{prefix}.writer-idle-time-seconds|netty-websocket.writer-idle-time-seconds\n|allIdleTimeSeconds|{prefix}.all-idle-time-seconds|netty-websocket.all-idle-time-seconds\n\n### 自定义Favicon\n配置favicon的方式与spring-boot中完全一致。只需将`favicon.ico`文件放到classpath的根目录下即可。如下:\n```\nsrc/\n  +- main/\n    +- java/\n    |   + \u003csource code\u003e\n    +- resources/\n        +- favicon.ico\n```\n\n### 自定义错误页面\n配置自定义错误页面的方式与spring-boot中完全一致。你可以添加一个 `/public/error` 目录，错误页面将会是该目录下的静态页面，错误页面的文件名必须是准确的错误状态或者是一串掩码,如下：\n```\nsrc/\n  +- main/\n    +- java/\n    |   + \u003csource code\u003e\n    +- resources/\n        +- public/\n            +- error/\n            |   +- 404.html\n            |   +- 5xx.html\n            +- \u003cother public assets\u003e\n```  \n\n### 多端点服务\n- 在[快速启动](#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B)的基础上，在多个需要成为端点的类上使用`@ServerEndpoint`、`@Component`注解即可\n- 可通过`ServerEndpointExporter.getInetSocketAddressSet()`获取所有端点的地址\n- 当地址不同时(即host不同或port不同)，使用不同的`ServerBootstrap`实例\n- 当地址相同,路径(path)不同时,使用同一个`ServerBootstrap`实例\n- 当多个端点服务的port为0时，将使用同一个随机的端口号\n- 当多个端点的port和path相同时，host不能设为`\"0.0.0.0\"`，因为`\"0.0.0.0\"`意味着绑定所有的host\n\n### 效果展示\n通过两个端点服务提供两个socket连接\n第一个：ws://127.0.0.1:8088\n\n![](https://i.imgur.com/yzRSfr1.jpg)\n\n第二个：ws://127.0.0.1:80\n![](https://i.imgur.com/r90vH0z.jpg)\n\n### 感谢\n谢谢这位大佬提供如此简单的开发框架：[Yeauty](https://gitee.com/Yeauty/netty-websocket-spring-boot-starter)\n\n### 问题建议\n\n- 联系我的邮箱：ilovey_hwy@163.com\n- 我的博客：http://www.hwy.ac.cn\n- GitHub：https://github.com/HWYWL","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhwywl%2Fnetty-websocket-spring-boot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhwywl%2Fnetty-websocket-spring-boot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhwywl%2Fnetty-websocket-spring-boot/lists"}