Netty框架(Netty-3.5.7.Final)来实现WebSocket服务端
WebSocketServer.java
import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; public class WebSocketServer { private final int port; public WebSocketServer(int port) { this.port = port; } public void run() { // 设置 Socket channel factory ServerBootstrap bootstrap = new ServerBootstrap( new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // 设置 Socket pipeline factory bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); // 启动服务,开始监听 bootstrap.bind(new InetSocketAddress(port)); // 打印提示信息 System.out.println("Web socket server started at port " + port + '.'); System.out.println("Open your browser and navigate to http://localhost:" + port + '/'); } public static void main(String[] args) { int port; if (args.length > 0) { port = Integer.parseInt(args[0]); } else { port = 8080; } new WebSocketServer(port).run(); } }
WebSocketServerPipelineFactory.java
import static org.jboss.netty.channel.Channels.*; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.handler.codec.http.HttpChunkAggregator; import org.jboss.netty.handler.codec.http.HttpRequestDecoder; import org.jboss.netty.handler.codec.http.HttpResponseEncoder; public class WebSocketServerPipelineFactory implements ChannelPipelineFactory { public ChannelPipeline getPipeline() throws Exception { // pipeline 的配置与 逻辑 ChannelPipeline pipeline = pipeline(); pipeline.addLast("decoder", new HttpRequestDecoder()); pipeline.addLast("aggregator", new HttpChunkAggregator(65536)); pipeline.addLast("encoder", new HttpResponseEncoder()); pipeline.addLast("handler", new WebSocketServerHandler()); return pipeline; } }
WebSocketServerHandler.java
import static org.jboss.netty.handler.codec.http.HttpHeaders.*; import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*; import static org.jboss.netty.handler.codec.http.HttpMethod.*; import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*; import static org.jboss.netty.handler.codec.http.HttpVersion.*; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponse; import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame; import org.jboss.netty.handler.codec.http.websocketx.PongWebSocketFrame; import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame; import org.jboss.netty.handler.codec.http.websocketx.WebSocketFrame; import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.util.CharsetUtil; public class WebSocketServerHandler extends SimpleChannelUpstreamHandler { private static final InternalLogger logger = InternalLoggerFactory .getInstance(WebSocketServerHandler.class); private static final String WEBSOCKET_PATH = "/websocket"; private WebSocketServerHandshaker handshaker; @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // 处理接受消息 Object msg = e.getMessage(); if (msg instanceof HttpRequest) { handleHttpRequest(ctx, (HttpRequest) msg); } else if (msg instanceof WebSocketFrame) { handleWebSocketFrame(ctx, (WebSocketFrame) msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { // 处理异常情况 e.getCause().printStackTrace(); e.getChannel().close(); } private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { // 只接受 HTTP GET 请求 if (req.getMethod() != GET) { sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Websocket 握手开始 WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( getWebSocketLocation(req), null, false); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); } else { handshaker.handshake(ctx.getChannel(), req).addListener( WebSocketServerHandshaker.HANDSHAKE_LISTENER); } } private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { // Websocket 握手结束 if (frame instanceof CloseWebSocketFrame) { handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame); return; } else if (frame instanceof PingWebSocketFrame) { ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); return; } else if (!(frame instanceof TextWebSocketFrame)) { throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass().getName())); } // 处理接受到的数据(转成大写)并返回 String request = ((TextWebSocketFrame) frame).getText(); if (logger.isDebugEnabled()) { logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); } ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); } private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { // 返回 HTTP 错误页面 if (res.getStatus().getCode() != 200) { res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8)); setContentLength(res, res.getContent().readableBytes()); } // 发送返回信息并关闭连接 ChannelFuture f = ctx.getChannel().write(res); if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { f.addListener(ChannelFutureListener.CLOSE); } } private static String getWebSocketLocation(HttpRequest req) { return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH; } }
websocket.html
<html><head><title>Web Socket Client</title></head> <body> <script type="text/javascript"> var socket; if (!window.WebSocket) { window.WebSocket = window.MozWebSocket; } // Javascript Websocket Client if (window.WebSocket) { socket = new WebSocket("ws://localhost:8080/websocket"); socket.onmessage = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + '\n' + event.data }; socket.onopen = function(event) { var ta = document.getElementById('responseText'); ta.value = "Web Socket opened!"; }; socket.onclose = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + "Web Socket closed"; }; } else { alert("Your browser does not support Web Socket."); } // Send Websocket data function send(message) { if (!window.WebSocket) { return; } if (socket.readyState == WebSocket.OPEN) { socket.send(message); } else { alert("The socket is not open."); } } </script> <h3>Send :</h3> <form onsubmit="return false;"> <input type="text" name="message" value="Hello World!"/><input type="button" value="Send Web Socket Data" onclick="send(this.form.message.value)" /> <h3>Receive :</h3> <textarea id="responseText" style="width:500px;height:300px;"></textarea> </form> </body> </html>
相关推荐
在"Netty实现WebSocket例子"中,我们将探讨如何使用Netty来搭建WebSocket服务器,并实现客户端与服务器之间的双向通信。首先,我们需要理解WebSocket的基本概念和工作原理。WebSocket协议是基于TCP的,它通过HTTP的...
Netty和WebSocket是现代网络应用开发中的两个重要技术,它们结合使用可以构建高效、实时的双向通信聊天室。本文将详细介绍这两个技术以及如何利用它们创建一个支持私聊功能的聊天室。 **Netty简介** Netty是一个高...
本篇将深入探讨Netty与WebSocket的结合,以及如何利用Netty构建WebSocket服务器。 首先,Netty是一个高性能、异步事件驱动的网络应用框架,它简化了Java网络编程,特别适合用于创建高并发、低延迟的服务。WebSocket...
在本文中,我们将深入探讨如何利用 Netty 和 WebSocket 技术实现通信,以及 `callServer` 文件可能包含的内容。 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它为 Web 应用程序提供了低延迟、双向通信...
在这个例子中,可能包含了实现WebSocket服务器端逻辑的Servlet或过滤器,以及相关的配置文件。 总结来说,"websocket+tomcat+jetty+netty"这个主题涵盖了WebSocket协议及其在不同服务器框架中的实现。Tomcat、Jetty...
在本“Netty 聊天例子”中,我们将深入探讨如何利用 Netty 构建一个简单的聊天应用,这对于初学者来说是一个很好的起点。 **Netty 基础** Netty 的核心组件包括 Channel、Bootstrap、Pipeline 和 EventLoopGroup。...
在这个“netty5_兼容tcp、websocket小例子”中,我们将探讨如何利用Netty 5版本实现TCP和WebSocket的兼容,并实现信息的广播功能。TCP是一种面向连接的、可靠的传输层协议,而WebSocket则是一种在Web上提供全双工...
这个例子展示了如何使用 Netty 构建一个简单的 WebSocket 服务器,它接收文本帧并将其反射回客户端。你可以根据实际需求扩展 `WebSocketServerHandler`,例如添加认证、处理特定的消息类型,或者与其他服务进行集成...
这个压缩包“netty各种例子(基于netty各种例子。).zip”显然是一个包含Netty示例代码的资源包,可以帮助开发者更好地理解和使用Netty框架。 在Java世界中,Netty因其高效、易用和丰富的特性而被广泛应用于多种场景...
在这个例子中,客户端订阅了`/topic/messages`主题,当服务器发送消息到这个主题时,客户端会收到消息。同时,客户端也能够通过`stompClient.send()`方法向服务器发送消息。 总结来说,Spring Boot通过集成...
直接附代码 前端代码: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request....
通过 Netty 的官网例子,你可以深入学习这些概念并了解如何在实际项目中运用。官方示例通常覆盖了基础到高级的各种用法,是理解和掌握 Netty4.0 的良好起点。你可以从 netty-4.0 压缩包中的源代码开始,逐步分析和...
这个压缩包文件"java Netty 框架例子源码.rar"很可能包含了一系列示例代码,帮助我们了解和学习如何在实际项目中使用 Netty。 Netty 的核心组件包括: 1. **Channel**:是 Netty 中的基本概念,代表一个打开的连接...
这个“Netty 官方例子”压缩包包含了一系列官方提供的示例代码,旨在帮助开发者更好地理解和运用 Netty 框架。通过在 IntelliJ IDEA(简称 IDEA)中运行这些例子,我们可以深入学习 Netty 的核心特性和使用方式。 1...
4. **WebSocket服务器和客户端**:WebSocket提供双向通信,这个例子展示了如何用Netty实现WebSocket服务器和客户端,处理文本和二进制帧。 5. **TCP和UDP通信**:Netty支持TCP和UDP协议,你可以找到处理TCP连接和...
这是一个基于netty的简单的websocket长链接demo,只是一个简单的例子,但是可以作为参考打开思路
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护...随着对Netty理解的深入,你将能够构建复杂的网络应用,如WebSocket服务器、RPC框架等。记得不断实践和探索,Netty的强大功能等待你去挖掘。
请注意,这个例子可能只是一个基础的 HTTP 代理,实际应用中可能需要考虑更多因素,比如支持 HTTPS、处理 WebSocket 连接、支持多种代理协议(如 SOCKS4/5),以及错误处理和性能优化。 在运行示例时,你可能需要在...
Netty 是一个高性能、异步事件驱动的网络...这只是一个入门级的实例,实际应用中,Netty 可以处理更复杂的网络通信需求,如WebSocket、HTTP 协议等。不断学习和实践,你将能掌握更多关于 Netty 的高级特性和优化技巧。
Netty是由JBOSS提供的一个Java开源框架,它提供了多种网络通信所需的组件,包括TCP、UDP、HTTP、WebSocket等多种协议的支持。Netty的核心是其异步事件驱动模型,通过使用NIO(非阻塞I/O)和线程池来实现高效的网络...