Coder Social home page Coder Social logo

yeautyye / netty-websocket-spring-boot-starter Goto Github PK

View Code? Open in Web Editor NEW
1.7K 58.0 523.0 151 KB

:rocket: lightweight high-performance WebSocket framework ( 轻量级、高性能的WebSocket框架)

License: Apache License 2.0

Java 100.00%
spring-boot netty netty-spring-boot-starter spring-boot-starter annotation im chat asynchronous websocket spring-boot-websocket

netty-websocket-spring-boot-starter's Introduction

netty-websocket-spring-boot-starter License

中文文档 (Chinese Docs)

About

netty-websocket-spring-boot-starter will help you develop WebSocket server by using Netty in spring-boot,it is easy to develop by using annotation like spring-websocket

Requirement

  • jdk version 1.8 or 1.8+

Quick Start

  • add Dependencies:
	<dependency>
		<groupId>org.yeauty</groupId>
		<artifactId>netty-websocket-spring-boot-starter</artifactId>
		<version>0.12.0</version>
	</dependency>
  • annotate @ServerEndpoint on endpoint class,and annotate @BeforeHandshake,@OnOpen,@OnClose,@OnError,@OnMessage,@OnBinary,@OnEvent on the method. e.g.
@ServerEndpoint(path = "/ws/{arg}")
public class MyWebSocket {

    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        session.setSubprotocols("stomp");
        if (!"ok".equals(req)){
            System.out.println("Authentication failed!");
            session.close();
        }
    }
    
    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        System.out.println("new connection");
        System.out.println(req);
    }

    @OnClose
    public void onClose(Session session) throws IOException {
       System.out.println("one connection closed"); 
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println(message);
        session.sendText("Hello Netty!");
    }

    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes); 
    }

    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }

}
  • use Websocket client to connect ws://127.0.0.1:80/ws/xxx

Annotation

@ServerEndpoint

declaring ServerEndpointExporter in Spring configuration,it will scan for WebSocket endpoints that be annotated with ServerEndpoint . beans that be annotated with ServerEndpoint will be registered as a WebSocket endpoint. all configurations are inside this annotation ( e.g. @ServerEndpoint("/ws") )

@BeforeHandshake

when there is a connection accepted,the method annotated with @BeforeHandshake will be called
classes which be injected to the method are:Session,HttpHeaders...

@OnOpen

when there is a WebSocket connection completed,the method annotated with @OnOpen will be called
classes which be injected to the method are:Session,HttpHeaders...

@OnClose

when a WebSocket connection closed,the method annotated with @OnClose will be called classes which be injected to the method are:Session

@OnError

when a WebSocket connection throw Throwable, the method annotated with @OnError will be called classes which be injected to the method are:Session,Throwable

@OnMessage

when a WebSocket connection received a message,the method annotated with @OnMessage will be called classes which be injected to the method are:Session,String

@OnBinary

when a WebSocket connection received the binary,the method annotated with @OnBinary will be called classes which be injected to the method are:Session,byte[]

@OnEvent

when a WebSocket connection received the event of Netty,the method annotated with @OnEvent will be called classes which be injected to the method are:Session,Object

Configuration

all configurations are configured in @ServerEndpoint's property

property default description
path "/" path of WebSocket can be aliased for value
host "0.0.0.0" host of WebSocket."0.0.0.0" means all of local addresses
port 80 port of WebSocket。if the port equals to 0,it will use a random and available port(to get the port Multi-Endpoint)
bossLoopGroupThreads 0 num of threads in bossEventLoopGroup
workerLoopGroupThreads 0 num of threads in workerEventLoopGroup
useCompressionHandler false whether add WebSocketServerCompressionHandler to pipeline
optionConnectTimeoutMillis 30000 the same as ChannelOption.CONNECT_TIMEOUT_MILLIS in Netty
optionSoBacklog 128 the same as ChannelOption.SO_BACKLOG in Netty
childOptionWriteSpinCount 16 the same as ChannelOption.WRITE_SPIN_COUNT in Netty
childOptionWriteBufferHighWaterMark 64*1024 the same as ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK in Netty,but use ChannelOption.WRITE_BUFFER_WATER_MARK in fact.
childOptionWriteBufferLowWaterMark 32*1024 the same as ChannelOption.WRITE_BUFFER_LOW_WATER_MARK in Netty,but use ChannelOption.WRITE_BUFFER_WATER_MARK in fact.
childOptionSoRcvbuf -1(mean not set) the same as ChannelOption.SO_RCVBUF in Netty
childOptionSoSndbuf -1(mean not set) the same as ChannelOption.SO_SNDBUF in Netty
childOptionTcpNodelay true the same as ChannelOption.TCP_NODELAY in Netty
childOptionSoKeepalive false the same as ChannelOption.SO_KEEPALIVE in Netty
childOptionSoLinger -1 the same as ChannelOption.SO_LINGER in Netty
childOptionAllowHalfClosure false the same as ChannelOption.ALLOW_HALF_CLOSURE in Netty
readerIdleTimeSeconds 0 the same as readerIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
writerIdleTimeSeconds 0 the same as writerIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
allIdleTimeSeconds 0 the same as allIdleTimeSeconds in IdleStateHandler and add IdleStateHandler to pipeline when it is not 0
maxFramePayloadLength 65536 Maximum allowable frame payload length.
useEventExecutorGroup true Whether to use another thread pool to perform time-consuming synchronous business logic
eventExecutorGroupThreads 16 num of threads in bossEventLoopGroup
sslKeyPassword ""(mean not set) the same as server.ssl.key-password in spring-boot
sslKeyStore ""(mean not set) the same as server.ssl.key-store in spring-boot
sslKeyStorePassword ""(mean not set) the same as server.ssl.key-store-password in spring-boot
sslKeyStoreType ""(mean not set) the same as server.ssl.key-store-type in spring-boot
sslTrustStore ""(mean not set) the same as server.ssl.trust-store in spring-boot
sslTrustStorePassword ""(mean not set) the same as server.ssl.trust-store-password in spring-boot
sslTrustStoreType ""(mean not set) the same as server.ssl.trust-store-type in spring-boot
corsOrigins {}(mean not set) the same as @CrossOrigin#origins in spring-boot
corsAllowCredentials ""(mean not set) the same as @CrossOrigin#allowCredentials in spring-boot

Configuration by application.properties

You can get the configurate of application.properties by using ${...} placeholders. for example:

  • first,use ${...} in @ServerEndpoint
@ServerEndpoint(host = "${ws.host}",port = "${ws.port}")
public class MyWebSocket {
    ...
}
  • then configurate in application.properties
ws.host=0.0.0.0
ws.port=80

Custom Favicon

The way of configure favicon is the same as spring-boot.If favicon.ico is presented in the root of the classpath,it will be automatically used as the favicon of the application.the example is following:

src/
  +- main/
      +- java/
      |   + <source code>
      +- resources/
          +- favicon.ico

Custom Error Pages

The way of configure favicon is the same as spring-boot.you can add a file to an /public/error folder.The name of the error page should be the exact status code or a series mask.the example is following:

src/
  +- main/
      +- java/
      |   + <source code>
      +- resources/
          +- public/
              +- error/
              |   +- 404.html
              |   +- 5xx.html
              +- <other public assets>

Multi Endpoint

  • base on Quick-Start,use annotation @ServerEndpoint and @Component in classes which hope to become a endpoint.
  • you can get all socket addresses in ServerEndpointExporter.getInetSocketAddressSet().
  • when there are different addresses(different host or different port) in WebSocket,they will use different ServerBootstrap instance.
  • when the addresses are the same,but path is different,they will use the same ServerBootstrap instance.
  • when multiple port of endpoint is 0 ,they will use the same random port
  • when multiple port of endpoint is the same as the path,host can't be set as "0.0.0.0",because it means it binds all of the addresses

Change Log

0.8.0

  • Auto-Configuration

0.9.0

  • Support RESTful by @PathVariable
  • Get param by@RequestParam from query
  • Remove ParameterMap ,instead of @RequestParam MultiValueMap
  • Add @BeforeHandshake annotation,you can close the connect before handshake
  • Set sub-protocol in @BeforeHandshake event
  • Remove the @Component on endpoint class
  • Update Netty version to 4.1.44.Final

0.9.1

  • Bug fixed : it was null when using @RequestParam MultiValueMap to get value
  • Update Netty version to 4.1.45.Final

0.9.2

  • There are compatibility version under 0.8.0 that can configure the ServerEndpointExporter manully

0.9.3

  • Bug fixed :when there is no @BeforeHandshake , NullPointerException will appear

0.9.4

  • Bug fixed :when there is no @BeforeHandshake , Session in OnOpen is null

0.9.5

  • Bug fixed :Throwable in OnError event is null

0.10.0

  • Modified the default value of bossLoopGroupThreads to 1
  • Supports configuring useEventExecutorGroup to run synchronous and time-consuming business logic in EventExecutorGroup, so that the I/O thread is not blocked by a time-consuming task
  • SSL supported
  • CORS supported
  • Update Netty version to 4.1.49.Final

0.11.0

  • When the ServerEndpoint class is proxied by CGLIB (as with AOP enhancement), it still works

0.12.0

  • @enableWebSocket adds the scanBasePackages attribute
  • @serverEndpoint no longer depends on @Component
  • Update Netty version to 4.1.67.Final

netty-websocket-spring-boot-starter's People

Contributors

dependabot[bot] avatar jayicez avatar pengyongjianpyj avatar sizne avatar yeautyye avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

netty-websocket-spring-boot-starter's Issues

@ServerEndpoint 设置端口后报403 不设置端口使用默认80端口正常

@serverendpoint(value = "/ws", host = "127.0.0.1", port = 3000)
前端访问响应403,后台无任何错误
启动日志:
2018-12-03 22:18:23.076 DEBUG 36760 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0x934e13e6] REGISTERED
2018-12-03 22:18:23.076 DEBUG 36760 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0x934e13e6] BIND: /127.0.0.1:3000
2018-12-03 22:18:23.080 DEBUG 36760 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0x934e13e6, L:/127.0.0.1:3000] ACTIVE
前端访问后响应403
GET ws://127.0.0.1:3000/ws?userId=2222222222 HTTP/1.1
Host: 127.0.0.1:3000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
Upgrade: websocket
Origin: file://
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Sec-WebSocket-Key: IbOqN91LFZ1SCO6AVHXl0A==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
image
使用80端口正常连接

后台设置了https 前端请求用wss无响应 后台无报错

image
前端请求
socket = new WebSocket("wss://127.0.0.1:80/ws?userId=admin"); 会报错
但是socket = new WebSocket("ws://127.0.0.1:80/ws?userId=admin"); 不会报错 正常连接
我的理解https对应wss是不是理解错了?

后台必须是要https才能访问的
2018-12-03 23:07:47.280 DEBUG 46804 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0xeb16011e, L:/127.0.0.1:80] READ: [id: 0x8059199d, L:/127.0.0.1:80 - R:/127.0.0.1:56556]
2018-12-03 23:07:47.281 DEBUG 46804 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0xeb16011e, L:/127.0.0.1:80] READ COMPLETE
2018-12-03 23:07:47.312 DEBUG 46804 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0xeb16011e, L:/127.0.0.1:80] READ: [id: 0x4e0e326c, L:/127.0.0.1:80 - R:/127.0.0.1:56557]
2018-12-03 23:07:47.312 DEBUG 46804 --- [ntLoopGroup-2-1] io.netty.handler.logging.LoggingHandler : [id: 0xeb16011e, L:/127.0.0.1:80] READ COMPLETE

部署至阿里云服务器时出现的问题

maven打包时,@serverendpoint的host属性如果直接设置阿里云服务器公网ip,无法打包。

当我将host设置为0.0.0.0时,打包正常,客户端也能正常获取到推送的数据,但是会报一个远程主机强迫关闭了一个现有的连接。

2019-04-11 16:11:44.523 [nioEventLoopGroup-3-2] ERROR org.yeauty.pojo.PojoEndpointServer - Unexpected exception:
java.lang.NullPointerException: null
at sun.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.yeauty.pojo.PojoEndpointServer.doOnError(PojoEndpointServer.java:134)
at org.yeauty.standard.HttpServerHandler.exceptionCaught(HttpServerHandler.java:96)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:285)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:264)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:256)
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:131)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:285)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:264)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:256)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireExceptionCaught(CombinedChannelDuplexHandler.java:426)
at io.netty.channel.ChannelHandlerAdapter.exceptionCaught(ChannelHandlerAdapter.java:87)
at io.netty.channel.CombinedChannelDuplexHandler$1.fireExceptionCaught(CombinedChannelDuplexHandler.java:147)
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:131)
at io.netty.channel.CombinedChannelDuplexHandler.exceptionCaught(CombinedChannelDuplexHandler.java:233)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:285)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:264)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:256)
at io.netty.channel.DefaultChannelPipeline$HeadContext.exceptionCaught(DefaultChannelPipeline.java:1401)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:285)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:264)
at io.netty.channel.DefaultChannelPipeline.fireExceptionCaught(DefaultChannelPipeline.java:953)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.handleReadException(AbstractNioByteChannel.java:125)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:174)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:563)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Unknown Source)
2019-04-11 16:11:44.807 [nioEventLoopGroup-3-3] ERROR org.yeauty.pojo.PojoEndpointServer - Unexpected exception:
java.io.IOException: 远程主机强迫关闭了一个现有的连接。
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(Unknown Source)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
at sun.nio.ch.IOUtil.read(Unknown Source)
at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:347)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:563)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Unknown Source)

项目部分附件如下
test.zip

正常启动Application类 然后报错--

您好:大神能帮看下吗,为啥
启动报:
java.lang.IllegalStateException: Failed to register ServerEndpointConfig: org.yeauty.standard.ServerEndpointConfig@4047d2d9
y 4mmo wjfx6geci7 1 krj

多端点描述疑惑点

你好,请问下“当地址相同,路径(path)不同时,使用同一个ServerBootstrap实例”,这句话怎么理解?
我的理解是:多@serverendpoint(path = UrlMappingConsts.V1_BOOTSTRAP)路径配置(地址+端口不变)那么他们的session是同一个? 可以这么理解吗

或者说我需要实现这种功能请问下你的框架是否支持?
Tips 我之所以想通过这种方式区分主要目的是能否让业务能单一化在某个类中。

咨询一下,要做两个人PK的答题游戏能实现吗

您好,我现在要做两个人PK的答题游戏,大致流程如下
1、登录系统,标识为所有登录的人是在线的
2、某用户发起PK游戏,建立房间,给在线用户发起消息,最先进入的人与发起者进行游戏
3、系统推送题目给在同一房间的两个人,进行PK,相互推送答题结果

性能

您好,请问做过压测什么的吗,或者有过生产实践没,各方面性能怎么样?

session 对象不能序列化吗?

我想在连接开启的时候把session 和 用户token 做一个redis键值对保存。方便业务里面使用。但是session 没有提供序列化

client在连接server后报Connection reset by peer

client在连接server的事件后,很快会触发一次异常,具体信息为【Connection reset by peer 】,server 端的连接处理并没有什么报错,难道是client的异常或者处理顺序导致的?求助~

@onOpen注解会和aspectj注解冲突吗?

我添加了一个切面,代码如下:

@Aspect
@Component
public class ServiceLogAspect {
    @Around("execution(* com.test.server.WebSocketServer.onOpen(..))")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        Object result;
        System.out.println("around");
        try {
            result = jp.proceed();
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
}
@OnOpen
public void onOpen(Session session, HttpHeaders headers, ParameterMap parameterMap) throws IOException {
        System.out.println("session:" + session + ", new connection"); // not executed

@OnMessage
public void OnMessage(Session session, String message) {
        System.out.println("session:" + session + ", message:" + message);
}

添加这个切面之后,@onopen函数就不触发了,around-advice中的代码也不会执行;但如果把切面中的onOpen函数换成onMessage函数则一切正常,around-advice中的代码也能够执行。

这是因为@onopen注解和aspectj注解有冲突吗?

关闭WebSocket

文档中只说明了如何开始,没有说明如何关闭啊!

我这边想实现群聊和一对一聊天

我看了问题《一对一发消息应该怎么做》这边我发现貌似没办法通过 "/netty/{userId}" 这种方式把userId获取到对应的变量中去,不支持socket的PathParam注解啊。用“/netty”可以访问,用 "/netty/{userId}"直接报404.

wildcard support

Hello,
is it possible to make path wildard I tried:
path =/**
I tried it like this but instead of wildcard it only allows me to create connection uwint path:
new WebSocket("ws://127.0.0.1:8085/**"); //javascript
new WebSocket("ws://127.0.0.1:8085/something/something /asd");//javascript this douesnt work

but it deonst work as expected

Thanks

建议把客户端的ping直接拿出来单独监听

private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        if (frame instanceof TextWebSocketFrame) {
            pojoEndpointServer.doOnMessage(ctx, frame);
            return;
        }
       // 这里你直接给返回了 建议把此处单独拿出来 以及下面的Pong
        if (frame instanceof PingWebSocketFrame) {
            ctx.writeAndFlush(new PongWebSocketFrame(frame.content().retain()));
            return;
        }
        if (frame instanceof CloseWebSocketFrame) {
            ctx.writeAndFlush(frame.retainedDuplicate()).addListener(ChannelFutureListener.CLOSE);
            return;
        }
        if (frame instanceof BinaryWebSocketFrame) {
            pojoEndpointServer.doOnBinary(ctx, frame);
            return;
        }
        if (frame instanceof PongWebSocketFrame) {
            return;
        }
    }

Content-length of blob is 0?

The image sended is not displayed in the browser using the following code:

var ws = new WebSocket('ws://127.0.0.1:8080')
ws.binaryType = 'blob'

压缩设置逻辑 问题

压缩逻辑的位置应该跟pipeline.addLast(new HttpServerHandler(pojoEndpointServer, config)); 平行.


            .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new HttpObjectAggregator(65536));
                        if (config.isUseCompressionHandler()) {
                            pipeline.addLast(new WebSocketServerCompressionHandler());
                        }
                        pipeline.addLast(new HttpServerHandler(pojoEndpointServer, config));
                    }
                });

域名连接失败

之前本地测试的时候是ip连接,可以正常了解,现在发布外网,连接的是域名地址,连接失败,这个需要怎么配置支持吗?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.