如何使用Netty在主电源中使用两个插座
我是一个Netty初学者,希望使用Netty同时运行服务器套接字和客户端套接字。但是,当我尝试它时,我只能运行一个套接字,而另一个无法运行。 实际上,我想要的是与Webbrowser的websocket通信,并将其传递到同一应用程序中的客户端套接字,以将其发送到TCP/IP套接字服务器。 谢谢你的帮助 这是我的密码:如何使用Netty在主电源中使用两个插座,netty,Netty,我是一个Netty初学者,希望使用Netty同时运行服务器套接字和客户端套接字。但是,当我尝试它时,我只能运行一个套接字,而另一个无法运行。 实际上,我想要的是与Webbrowser的websocket通信,并将其传递到同一应用程序中的客户端套接字,以将其发送到TCP/IP套接字服务器。 谢谢你的帮助 这是我的密码: public class WsServer { private int port; public WsServer(int port){ this
public class WsServer {
private int port;
public WsServer(int port){
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new WsServerInitializer());
Channel ch = b.bind(port).sync().channel();
System.out.println("Web socket server started at port " + port + '.');
System.out.println("Open your browser and navigate to http://localhost:" + port + '/');
ch.closeFuture().sync();
} finally {
InternalSocket.close();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class WsServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec-http", new HttpServerCodec());
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new WsSocketHandler());
}
}
public class WsSocketHandler extends WebSocketServerHandler {
private static final Logger logger = Logger.getLogger(WsSocketHandler.class);
protected static final String WEBSOCKET_PATH = "/websocket";
private WebSocketServerHandshaker handshaker;
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg)
throws Exception {
//super.channelRead0(ctx, msg);
if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg);
} else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
super.exceptionCaught(ctx, cause);
}
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
// Handle a bad request.
if (!req.getDecoderResult().isSuccess()) {
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
return;
}
// Allow only GET methods.
if (req.getMethod() != GET) {
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
return;
}
// Send the demo page and favicon.ico
if ("/".equals(req.getUri())) {
ByteBuf content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
setContentLength(res, content.readableBytes());
sendHttpResponse(ctx, req, res);
return;
}
if ("/favicon.ico".equals(req.getUri())) {
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND);
sendHttpResponse(ctx, req, res);
return;
}
// Handshake
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
getWebSocketLocation(req), null, false);
handshaker = wsFactory.newHandshaker(req);
if (handshaker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
} else {
handshaker.handshake(ctx.channel(), req);
}
}
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
// Check for closing frame
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
return;
}
if (frame instanceof PingWebSocketFrame) {
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
return;
}
if (!(frame instanceof TextWebSocketFrame)) {
throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass()
.getName()));
}
// Send the uppercase string back.
String receivedText = ((TextWebSocketFrame) frame).text();
//System.out.println("========= receivedText:" + receivedText);
handleWsSocketRequest(ctx, receivedText);
//logger.debug(String.format("%s received %s", ctx.channel(), receivedText));
//ctx.channel().write(new TextWebSocketFrame(receivedText.toUpperCase()));
}
private void handleWsSocketRequest(ChannelHandlerContext ctx, String receivedText){
System.out.println("[WebSocketHandler]" + receivedText);
if (StringUtils.isBlank(receivedText)) return;
try {
//InternalClient client = InternalClient.getInstance("localhost", 31200);
//client.send(receivedText);
// } catch (Exception e1) {
//e1.printStackTrace();
//}
//}
protected ChannelFuture send(ChannelHandlerContext ctx, String msg){
System.out.println(String.format("%s sent: %s", ctx.channel(), msg));
return ctx.channel().write(new TextWebSocketFrame(msg));
}
protected static void sendHttpResponse(
ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
// Generate an error page if response getStatus code is not OK (200).
if (res.getStatus().code() != 200) {
ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
res.content().writeBytes(buf);
buf.release();
setContentLength(res, res.content().readableBytes());
}
// Send the response and close the connection if necessary.
ChannelFuture f = ctx.channel().write(res);
ctx.channel().flush();
if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE);
}
}
protected static String getWebSocketLocation(FullHttpRequest req) {
return "ws://" + req.headers().get(HOST) + WEBSOCKET_PATH;
}
}
public class InternalClient {
private String host;
private int port;
private InternalClientHandler handler;
private InternalClient(String host, int port){
this.host = host;
this.port = port;
handler = new InternalClientHandler();
}
public void run() throws Exception {
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap(); // (1)
b.group(workerGroup); // (2)
b.channel(NioSocketChannel.class); // (3)
b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
b.handler(new InternalClietnIntializer());
// Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (5)
System.out.println("[InternalClient] Connects to " + host + ":" + port + '.');
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
public void send(String msg){
handler.send(msg);
}
}
public class InternalClietnIntializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// On top of the SSL handler, add the text line codec.
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("handler", new InternalClientHandler());
}
}
public class InternalClientHandler extends ChannelInboundHandlerAdapter {
ChannelHandlerContext context;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.context = ctx;
System.out.println("[InternalClientHandler]channelActive");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
System.out.println("channelRead ");
String recvText = "" + msg;
System.out.println("###[InternalClientHandler]Received###" + recvText);
if (StringUtils.isBlank(recvText)){
return;
}
}
public void send(String msg) {
if (context!=null){
context.channel().writeAndFlush(msg + "\r\n");
System.out.println("###[InternalClientHandler]Sent###" + msg + "\r\n");
}
}
}
public class ServerMain {
public static void main(String[] args) throws Exception {
int port = 31300;
try {
WsServer server = new WsServer(port);
server.run();
//Below does not run
InternalClient client = new InternalClient("localhost", port+1000);
client.run();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
公共类WsServer{
专用int端口;
公共WsServer(int端口){
this.port=端口;
}
public void run()引发异常{
EventLoopGroup bossGroup=新的NioEventLoopGroup(1);
EventLoopGroup workerGroup=新的NioEventLoopGroup();
试一试{
ServerBootstrap b=新的ServerBootstrap();
b、 组(bossGroup、workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(新的WsServerInitializer());
Channel ch=b.bind(port.sync().Channel();
System.out.println(“Web套接字服务器在端口“+port+.”启动);
System.out.println(“打开浏览器并导航到http://localhost:“+端口+'/”);
ch.closeFuture().sync();
}最后{
InternalSocket.close();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
公共类WsServerInitializer扩展了ChannelInitializer{
@凌驾
public void initChannel(SocketChannel ch)引发异常{
ChannelPipeline=通道管道();
addLast(“codechttp”,新的HttpServerCodec());
pipeline.addLast(“聚合器”,新的HttpObjectAggregator(65536));
addLast(“handler”,新的WsSocketHandler());
}
}
公共类WsSocketHandler扩展了WebSocketServerHandler{
私有静态最终记录器Logger=Logger.getLogger(WsSocketHandler.class);
受保护的静态最终字符串WEBSOCKET_PATH=“/WEBSOCKET”;
私有WebSocketServerHandshaker握手器;
@凌驾
公共无效channelRead0(ChannelHandlerContext ctx,对象消息)
抛出异常{
//super.channelRead0(ctx,msg);
if(msg instanceof FullHttpRequest){
handleHttpRequest(ctx,(FullHttpRequest)msg);
}else if(msg instanceof WebSocketFrame){
扶手网架(ctx,(网架)msg);
}
}
@凌驾
公共无效channelReadComplete(ChannelHandlerContext ctx)引发异常{
超级通道读取完成(ctx);
}
@凌驾
公共无效例外情况(ChannelHandlerContext ctx,可丢弃原因)
抛出异常{
超级例外情况(ctx,原因);
}
私有void handleHttpRequest(ChannelHandlerContext ctx,FullHttpRequest req)引发异常{
//处理一个错误的请求。
如果(!req.getDecoderResult().isSuccess()){
sendHttpResponse(ctx,req,新的DefaultFullHttpResponse(HTTP_1_1,BAD_请求));
回来
}
//只允许GET方法。
if(req.getMethod()!=GET){
sendHttpResponse(ctx,req,新的DefaultFullHttpResponse(HTTP_1_1,禁止));
回来
}
//发送演示页面和favicon.ico
如果(“/”.equals(req.getUri())){
ByteBuf content=WebSocketServerIndexPage.getContent(getWebSocketLocation(req));
FullHttpResponse res=新的DefaultFullHttpResponse(HTTP_1_1,OK,content);
res.headers().set(CONTENT_TYPE,“text/html;charset=UTF-8”);
setContentLength(res,content.readableBytes());
发送HttpResponse(ctx、req、res);
回来
}
如果(“/favicon.ico”.equals(req.getUri())){
FullHttpResponse res=新的默认FullHttpResponse(HTTP_1_1,未找到);
发送HttpResponse(ctx、req、res);
回来
}
//握手
WebSocketServerHandshakerFactory wsFactory=新建WebSocketServerHandshakerFactory(
getWebSocketLocation(req),null,false);
握手器=wsFactory.newHandshaker(req);
if(握手器==null){
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
}否则{
握手器。握手(ctx.channel(),req);
}
}
私有void handleWebSocketFrame(ChannelHandlerContext ctx、WebSocketFrame){
//检查是否有闭合框架
if(CloseWebSocketFrame的帧实例){
handshaker.close(ctx.channel(),(CloseWebSocketFrame)frame.retain());
回来
}
if(PingWebSocketFrame的帧实例){
ctx.channel().write(新的PongWebSocketFrame(frame.content().retain());
回来
}
if(!(TextWebSocketFrame的帧实例)){
抛出新的UnsupportedOperationException(String.format(“%s帧类型不受支持”,frame.getClass())
.getName());
}
//将大写字符串发回。
字符串receivedText=((TextWebSocketFrame)frame.text();
//System.out.println(“=============receivedText:“+receivedText”);
HandleSSocketRequest(ctx,receivedText);
//debug(String.format(“%s已接收%s”,ctx.channel(),receivedText));
//ctx.channel().write(新的TextWebSocketFrame(receivedText.toUpperCase());
}
私有无效HandleSSocketRequest(ChannelHandlerContext ctx,字符串receivedText){
System.out.println(“[WebSocketHandler]”和receivedText);
如果(StringUtils.isBlank(receivedText))返回;
试一试{
//InternalClient=InternalClient.getInstance(“localhost”,31200);
//client.send(receivedText);
//}catch(异常e1){
//e1.printStackTrace();
//}
//}
受保护的ChannelFuture发送(ChannelHandlerContext ctx,字符串msg){
System.ou