开发者社区> 问答> 正文

Netty编写的服务器可以同时接收socket和websocket请求吗? 400 报错

Netty编写的服务器可以同时接收socket和websocket请求吗? 400 报错

最近做的项目需要写一个服务器,这个服务器必须又能接收socket请求又能接收websocket请求,因为我需要将小程序的websocket指令转发给服务器然后接收设备回传的数据(设备只能进行TCP连接,就是socket) 最后发送回手机端显示,看了网上要么就只接收socket,要么就只接收websocket,我就想像盼达,或者摩拜这种定位又是怎么实现的呢?他们同样可以在小程序下面进行定位,而他们车上的定位设备多半也只能进行tcp连接,我觉得可能是服务器定时请求定位数据然后储存起来,然后客户端直接请求数据库,有没有大神指点一下 

我尝试像这样把处理类写在一起,但是socket这边的请求每次都走到websocket那边去了

请问这个是怎么回事啊?

展开
收起
爱吃鱼的程序员 2020-06-04 16:17:48 1618 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    普通socket和websocket用不同的端口监听。

    ######分开来实现了监听,但有时候连接上后马上就掉线了######

    你把类名字设置为WebSocketHandler,难道就实现WebSocket的功能了?

    首先在你的WebSocketHandler中,重写方法

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

    判断msg的类型,第一次握手是Http协议,所以:

    // 判断Http
    msg instanceof FullHttpRequest
    
    // 判断WebSocket
    msg instanceof WebSocketFrame

    如果是Http且能正确解码

    ① 若Header里面含有Upgrade=websocket,则构造握手响应返回,就是你那个handshaker;

    ② 若不含有,则按照普通Http进行处理并响应

    若解码失败,返回失败的Http响应即可

    ######我做了你说的这几步,现在我把端口分开来监听了,但是有时候连接上马上就会进到channelInactive掉线,请问大概会是什么情况引起的?######服务器绑定不同的端口号######

    后端一个应用程序编写运行两个服务,一个socket,一个websocket,绑定不同的端口。

     

    你也可以部署多个服务,以定位举例,把定位那块做成RPC服务,对外提供tcp socket接口,其它服务不管是socket、websocket、http,都用统一的RPC接口调用。

    ######两个服务器之间怎么通信呢,这个还没搞过也######

    使用不同端口, 各自用自己的编解码类, 全局map存储 channel ,

    ######

    我现在正在做这个功能,我的服务器用的是一个,在第一个Handler中通过读取第一条消息来区分是websocket还是普通的socket,如果是websocket的话,第一条消息就是一个http报文信息,如果是socket的话,第一条消息可以自定义。

    这样就可以判断是什么方式连接,然后再动态的条件ChannelPipeline

    ######答主您好,我现在遇到了同样的问题,能给个示例代码或参考博客吗?非常感谢######

    博主您好,请问这个问题您解决了吗?我遇到了同样的问题,如果您解决了,能否给个示例代码或参考博客,万分感谢!

    ######我把server的代码贴下面了######
    public class Server {
    
        public void run(int socketport,int websocketport) throws Exception {
    
            EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap(); // (2)
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class) // (3)
                        .option(ChannelOption.SO_BACKLOG, 128)          // (5)
                        .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
                List<Integer> ports = new ArrayList(2);
                ports.add(socketport);
                ports.add(websocketport);
                Collection<Channel> channels = new ArrayList(ports.size());
                for (int port : ports){
                    Channel serverChannel = null;
                    if(port == 8081){
                        b.childHandler(new SimpleChatServerInitializer());
                        serverChannel = b.bind(port).sync().channel();
                    }else if (port == 8082){
                        b.childHandler(new WebSocketInitalizer());
                        serverChannel = b.bind(port).sync().channel();
                    }
                    ((ArrayList) channels).add(serverChannel);
                }
                System.out.println("Server 启动了");
                for (Channel ch : channels) {
                    ch.closeFuture().sync();
                }
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
                System.out.println("Server 关闭了");
            }
        }
    
    }

    功能实现了,主要就是同时监听两个端口,socket和websocker 的handler还是正常写

    ######感谢楼主。当时项目太忙,提问后两天没看到回复也就没回来看。后来找了一篇文章,按照文章的思路实现了一个端口同时接收两种连接。它是根据客户端连接的头部信息来区分连接类型,而不是根据端口来区分,比起你的方法更简洁一点。现在项目基本结束,我把实现的代码整理成博客:https://blog.csdn.net/NRlovestudy/article/details/93325965 。有需要的朋友可以参考下。######

    我的实现方式是这样的:

    主要是判断连接上以后使用第一条消息来区分是websocket还是socket



    然后是ClientControlHandler类

    重点也就这么几行代码,可能再判断是否是websocket协议的时候不太严谨,楼主可以设计下判断的方式,参考HTTP解码器。

    还有添加websocket解码器的时候需要调用一下channelRead方法,因为动态添加了处理器并不会立即执行。

    decode方法是我写的一个简单的解码器:读取106个字符是因为我的业务中socket连接发来的验证码的时候正好是106个字符。

    动态添加处理器的方法:

    2020-06-04 17:47:17
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
如何运维千台以上游戏云服务器 立即下载
网站/服务器取证 实践与挑战 立即下载
ECS块储存产品全面解析 立即下载