- 浏览: 115310 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
ron.luo:
干货,必须得顶。
JAXB使用经验总结 -
csdn_zuoqiang:
能否看下DWR的配置情况?谢谢
结合webservice实现dwr推送 -
友友水:
。。。。不好意思,无心之失,删不掉前一条评论
JAXB使用经验总结 -
友友水:
[/flash][/flash][/flash][/flash ...
JAXB使用经验总结 -
lihong11:
大哥,加加注释好不?看不懂唉
小玩dwr实现服务器推送
用main的形式在服务器上启动了一个netty服务,有端口有地址,可请求
package com.mazing.wx; import java.io.IOException; import java.io.InputStream; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.Configurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; /** * */ public class WxHttpServer { static {//指定初始化哪个log配置 try { InputStream is = WxHttpServer.class.getResourceAsStream("/log4j2-wx.xml"); ConfigurationSource cs = new ConfigurationSource(is); Configurator.initialize(null, cs); } catch (IOException e) { System.err.println(e); } } private static final Logger logger = LoggerFactory.getLogger(WxHttpServer.class); public void start(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码 ch.pipeline().addLast(new HttpResponseEncoder()); // server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码 ch.pipeline().addLast(new HttpRequestDecoder()); ch.pipeline().addLast(new HttpServerInboundHandler()); } }).option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } logger.info("Http server stopped ..."); } public static void main(String[] args) throws Exception { logger.info("http main ..."); WxHttpServer server = new WxHttpServer(); final WxAccessTokenReaderThread thread = new WxAccessTokenReaderThread(); thread.start(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { logger.info("shutdowning ..."); thread.stopRunning(); } }); logger.info("Http Server listening on 20090 ..."); server.start(20090); } }
package com.mazing.wx; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.InetSocketAddress; import static io.netty.handler.codec.http.HttpHeaders.Names.*; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * */ public class HttpServerInboundHandler extends ChannelInboundHandlerAdapter { private static Logger logger = LoggerFactory.getLogger(HttpServerInboundHandler.class); private HttpRequest request; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { request = (HttpRequest) msg; String uri = request.getUri(); InetSocketAddress insocket = (InetSocketAddress) ctx.channel() .remoteAddress(); String clientIP = insocket.getAddress().getHostAddress(); logger.info("uri: {}, ip: {}", uri, clientIP); } if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); buf.release(); String text = WxAccessTokenReaderThread.wxAccessToken + "|" + WxAccessTokenReaderThread.wxJsapiTicket; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(text.getBytes("UTF-8"))); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (HttpHeaders.isKeepAlive(request)) { response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } ctx.write(response); ctx.flush(); } } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage()); ctx.close(); } }
package com.mazing.wx; import com.fasterxml.jackson.core.type.TypeReference; import com.mazing.CommonConstants; import com.mazing.commons.utils.HttpClientUtils; import com.mazing.commons.utils.JsonUtils; import com.mazing.commons.utils.cfg.DesPropertiesEncoder; import com.mazing.core.remote.config.Config; import com.mazing.core.web.RestResult; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 读取微信 access token 的线程 * */ public class WxAccessTokenReaderThread extends Thread { private static final Logger logger = LoggerFactory.getLogger(WxAccessTokenReaderThread.class); private boolean running = true; /** * 获取间隔 */ private static final int INTERVAL = 2 * 60 * 1000; // access token 在 7200秒过期, private long TOKEN_TIMEOUT = 7200 * 1000L - INTERVAL; private long lastReadTime = 0L; private String appid = null; private String secret = null; /** * access token */ static volatile String wxAccessToken = ""; /** * jsapi_ticket */ static volatile String wxJsapiTicket = ""; public WxAccessTokenReaderThread() { super("WxAccessTokenReaderThread"); } public void stopRunning() { running = false; interrupt(); } @Override public void run() { logger.info("WxAccessTokenReaderThread started ..."); if (!readConfig()) { logger.error("读取配置错误,线程结束,请配置 group=weixin_mp 的内容。 "); running = false; } while (running) { long now = System.currentTimeMillis(); if (now - lastReadTime >= TOKEN_TIMEOUT) { try { readToken(); readTicket(); lastReadTime = now; } catch (Exception e) { logger.error("读取微信 access token / jsapi ticket 错误", e); } } try { sleep(INTERVAL); } catch (InterruptedException e) { break; } } logger.info("WxAccessTokenReaderThread stopped ..."); } /** * 读取配置,只读一次 * @throws Exception */ public boolean readConfig() { String json = HttpClientUtils.doGet(CommonConstants.CONFIG_DOMAIN + "/api/base/allConfigs"); // logger.info("wx#readConfig | http response | result: {}", json.substring(0, 10) + "***"); RestResult<List<Config>> result = JsonUtils.parseObject(json, new TypeReference<RestResult<List<Config>>>() { }); if (!(result.isSuccess())) { logger.warn("wx#readConfig#Failure | Failure Request | result: {}", json); return false; } final String groupCode = "weixin_mp"; DesPropertiesEncoder decoder = new DesPropertiesEncoder(); int found = 0; for (Config config : result.getObject()) { if (groupCode.equals(config.getGroupCode())) { if ("appid".equalsIgnoreCase(config.getConfigKey())) { appid = decoder.decode(config.getConfigValue()); found++; } else if ("secret".equalsIgnoreCase(config.getConfigKey())) { secret = decoder.decode(config.getConfigValue()); found++; } } if (found >= 2) break; } return found >= 2; } /** * 读取 access token */ private void readToken() { Map<String, String> params = new HashMap<>(4); params.put("grant_type", "client_credential"); params.put("appid", appid); params.put("secret", secret); String json = HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", 10000, params); if (StringUtils.isBlank(json)) { logger.error("读取微信 access token 错误"); } Map<String, Object> map = JsonUtils.parseObject(json.trim(), new TypeReference<Map<String, Object>>() { }); if (map.containsKey("access_token")) { wxAccessToken = (String) map.get("access_token"); logger.info("读取微信 access token 成功"); if (map.containsKey("expires_in")) { int expiresIn = ((Number)map.get("expires_in")).intValue(); logger.info("过期时间 (s):" + expiresIn); TOKEN_TIMEOUT = expiresIn * 1000L - INTERVAL; if (TOKEN_TIMEOUT < 1000) { TOKEN_TIMEOUT = 10 * 60 * 1000L - INTERVAL; } } } else { logger.error("读取微信 access token 错误:" + json); } } /** * 读取 jsapi_ticket */ private void readTicket() { Map<String, String> params = new HashMap<>(4); params.put("access_token", wxAccessToken); params.put("type", "jsapi"); String json = HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", 10000, params); Map<String, Object> map = JsonUtils.parseObject(json.trim(), new TypeReference<Map<String, Object>>() { }); int errcode = -1; if (map.get("errcode") != null) { errcode = ((Number) map.get("errcode")).intValue(); logger.info("读取微信 jsapi_ticket 结果,errcode: {}, errmsg: {}", errcode, map.get("errmsg")); if (errcode == 0) { wxJsapiTicket = (String) map.get("ticket"); logger.info("读取微信 jsapi_ticket 成功!"); } } else { logger.error("读取微信 jsapi_ticket 错误:" + json); } } }
以上代码在启动WxHttpServer 中的main后,也就相当于启动了端口为20090的服务了, 可以通过请求如:
http://123.40.50.60:20090/ 获取到 HttpServerInboundHandler 中写入的参数
WeixinAccessToken.ACCESS_TOKEN 和
WeixinAccessToken.JSAPI_TICKET
发表评论
-
动态多数据源实现
2019-12-18 12:58 444背景: 目前基于连接了mobile库 从库的 项目(sprin ... -
java快速读取大文件
2018-02-08 11:19 370public static String readCon ... -
微信JSSDK 使用
2016-05-26 11:49 1951获取微信JSAPI_TICKET package com ... -
安全性,加密
2016-03-07 15:55 657/** * 随机字符串集 */ pri ... -
并发队列
2015-12-03 15:26 640import java.util.concurrent ... -
一致性hash算法测试
2014-12-17 18:40 1311因为用memcached集群缓存数据,所以增删服务器节点 对缓 ... -
ant脚本编译部署java工程到tomcat服务器
2013-06-28 15:35 1099<?xml version="1.0& ... -
Myeclipse反向生成pojo及hibernate映射文件(由数据库表)
2013-03-18 14:38 1086在这之前请创建一个web工程,然后右键选择myeclipse- ... -
手写比较器comparator
2012-07-12 15:47 1297项目中需要对一些数据进行排序,应用到了个比较强大的比较器,感觉 ... -
copy到粘贴板
2012-05-22 11:39 1182直接上代码,实现了IE和火狐下的copy content ... -
取两个集合的交集数据
2011-08-30 11:13 1280List<String> a = new A ... -
常用正则表达式收藏
2011-04-26 12:26 7301。^\d+$ //匹配非负整数(正整数 + 0) 2。 ... -
对日期类型与String类型之间转换方法的小结
2011-03-07 19:25 1264关于日期的方法举例程序如下: package c ... -
线程同步
2011-02-26 10:47 837转自http://www.iteye.com/topic/16 ... -
java多线程
2011-02-26 08:15 918本文转载自 http://www.iteye.com/topi ... -
对java中反射的整理
2011-02-24 20:04 894什么是Java中的类反射: ... -
关于线程----线程间的数据共享
2011-02-19 19:45 1598当多个线程的执行代码来自同一个类的run方法,既称他们共 ...
相关推荐
总之,Netty为Android开发者提供了强大的网络通信能力,通过理解和实践,我们可以构建出稳定、高效、可扩展的网络应用。无论是在服务端处理大量并发请求,还是在客户端实现低延迟的数据传输,Netty都能成为你得力的...
Netty4.0学习笔记系列之三是关于构建简单的HTTP服务的教程,这主要涉及网络编程、服务器开发以及Java NIO(非阻塞I/O)的相关知识。Netty是一个高性能、异步事件驱动的网络应用程序框架,它使得开发可伸缩且稳定的...
在深入探讨 Netty 的实践学习案例之前,我们先了解一下 Netty 的核心特性: 1. **异步非阻塞 I/O**:Netty 基于 Java NIO(非阻塞I/O)构建,允许它处理大量并发连接,减少了线程创建和上下文切换的开销。 2. **零...
Netty不仅简化了网络编程的复杂性,还提供了丰富的特性和组件,使得开发人员能够快速构建出可靠且高效的网络服务。 Netty的核心特性包括: 1. **异步模型**:Netty基于Java NIO(非阻塞I/O)构建,采用异步事件...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。...通过学习这个项目,可以深入理解 Netty 在游戏服务器开发中的应用,以及如何构建高性能的网络服务。
Netty 是一个高性能、异步事件驱动的网络应用程序框架,常用于开发高并发、低延迟的网络服务。在处理网络通信时,数据通常以各种格式传输,包括...理解和掌握这些概念和实践技巧对于构建高效、可靠的网络应用至关重要。
Java物联网的Netty服务器是一种基于Java的高性能网络应用框架,主要应用于开发高并发...通过深入学习和实践这个项目,开发者可以掌握利用Netty构建物联网服务器的关键技术,为构建高效、可靠的物联网应用打下坚实基础。
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本文中,我们将深入探讨 Netty 的通讯实践...学习并应用 Netty,有助于构建高性能、稳定可靠的网络应用程序。
这个入门项目是学习WebSocket与Netty结合的一个好起点,通过实际操作,你可以更深入地理解WebSocket协议的工作原理,以及如何使用Netty构建高效稳定的WebSocket服务器。同时,对于前端开发人员,这也是一个了解...
综上所述,理解和掌握 Netty 通过端口调用关闭的机制对于构建可靠的网络应用至关重要。通过细致的配置、适当的监听器和异常处理,我们可以确保服务器能够安全、高效地运行和退出。在实践中,结合源码分析和使用工具...
Netty 是一个基于 Java 的高性能、异步事件驱动的网络应用...通过学习和实践这些知识点,你可以熟练掌握 Netty 并用其构建高性能的网络应用。在 "netty-4.1" 的文档和示例代码中,你会找到更多关于这些主题的详细信息。
在这个“netty3实现的websocket服务”项目中,开发者利用Netty 3版本构建了一个WebSocket服务器和一个简单的Web服务器,旨在帮助学习者深入理解Netty的工作原理以及如何基于Netty构建实际项目。 WebSocket协议是一...
总的来说,《Netty实战》这本书全面覆盖了Netty的基础到高级知识,通过实例教学,使读者能够深入理解Netty的工作原理,并具备使用Netty构建高性能网络应用的能力。对于想要提升Java网络编程技能,或者已经在使用...
Netty 是一个高性能、异步事件驱动的网络应用...通过以上知识点的学习和实践,你将能够熟练掌握Netty的基本用法,实现高性能的网络应用。在实际项目中,结合具体的业务需求,Netty可以展现出强大的灵活性和可扩展性。
4. **云服务**:云服务提供商利用 Netty 构建高可用、高性能的 API 网关和内部服务通信。 总之,《Netty 权威指南》507页的完整版教程将深入探讨这些知识点,并通过实例帮助读者掌握如何在实际项目中运用 Netty ...
总的来说,SpringBoot整合Netty的实践涉及到SpringBoot的应用构建、Netty的服务器和客户端创建、响应式编程模型、以及两者的交互和配置优化等多个层面。通过这个Demo,开发者能够更好地理解和掌握如何在SpringBoot...
通过学习和实践 Netty 实现的 WebSocket 服务,你可以构建出强大的实时通讯系统,适用于游戏、金融、物联网等多种场景。不过,实际生产环境中,还需要考虑负载均衡、容错恢复、安全性等更多因素,以确保服务的稳定性...
读书笔记:基于netty构建的web微服务应用框架最佳实践
Netty 的设计目标是提供一个灵活且高效的基础架构,允许开发者快速构建网络服务,同时避免常见的性能瓶颈。 2. **Netty 的主要特点** - **异步事件驱动**:Netty 使用非阻塞 I/O 模型,提高了系统的并发处理能力。...
这部分课程将理论与实践相结合,让学习者在实际项目中运用Netty5构建不同类型的RPC(远程过程调用)架构。这涵盖了Netty5在RPC通信中的应用,如TCP、UDP协议的实现,以及HTTP、WebSocket等常见协议的处理。学习者将...