Netty编写的服务器可以同时接收socket和websocket请求吗? 400 报错
最近做的项目需要写一个服务器,这个服务器必须又能接收socket请求又能接收websocket请求,因为我需要将小程序的websocket指令转发给服务器然后接收设备回传的数据(设备只能进行TCP连接,就是socket) 最后发送回手机端显示,看了网上要么就只接收socket,要么就只接收websocket,我就想像盼达,或者摩拜这种定位又是怎么实现的呢?他们同样可以在小程序下面进行定位,而他们车上的定位设备多半也只能进行tcp连接,我觉得可能是服务器定时请求定位数据然后储存起来,然后客户端直接请求数据库,有没有大神指点一下
我尝试像这样把处理类写在一起,但是socket这边的请求每次都走到websocket那边去了
请问这个是怎么回事啊?
普通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个字符。
动态添加处理器的方法:
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。