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

solomanwan 发布于 2018/08/13 16:40
阅读 2K+
收藏 1

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

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

请问这个是怎么回事啊?

加载中
1
渡世白玉
渡世白玉

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

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

你把类名字设置为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响应即可

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

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

 

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

s
solomanwan
两个服务器之间怎么通信呢,这个还没搞过也
0
k
kenneth123

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

0
8
8avaj

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

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

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

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

s
solomanwan
我把server的代码贴下面了
0
s
solomanwan
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还是正常写

0
8
8avaj

我的实现方式是这样的:

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



然后是ClientControlHandler类

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

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

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

动态添加处理器的方法:

返回顶部
顶部