论坛首页 Java企业应用论坛

网站系统中应用mina

浏览 17336 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (7)
作者 正文
   发表时间:2010-02-25  
rain2005 写道
直接使用socket连接池,长连接,最好是每线程一连接和数据库connection一样

他们又不负责操作socket
0 请登录后投票
   发表时间:2010-02-25  
sundoctor 写道
引用
在这里遇到了问题,接收后的数据该如何返回给客户端(浏览器端)

这个问题其实很简单,没有大家想的那么复杂,只是大家没有想到点子上而己,解决办法就是要将接收后的数据和当前请求联系起来就可以返回给客户端了,以下是简单的解决办法:

在车务通系统客户端,也就是浏览器页面,发出请求,调用mina客户端的Iosession.write()方法,发送请求前产生一个系统全局唯一标识,并将这个标识保存到Iosession中,如:
	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		
		response.setContentType("text/html;charset=utf-8");
		
		String param1 = request.getParameter("param1");

		// 创建客户端连接器
		IoConnector connector = new NioSocketConnector();
		// 设置事件处理器
		connector.setHandler(new ClientHandler());
		// 设置编码过滤器和按行读取数据模式
		connector.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
		// 创建连接
		ConnectFuture future = connector.connect(new InetSocketAddress(TARGET_IP, PORT));
		// 等待连接创建完成
		future.awaitUninterruptibly();
		// 获取连接会话
		IoSession session = future.getSession();

		// 产生当次发送请求标识,标识由客户端地址+随机数
		// 这里的标识只是一个例子,标识可以任何方法产生,只要保持在系统中的唯一性		
		String flag = request.getLocalAddr() + UUID.randomUUID().toString();
		//将标识保存到当前session中
		session.setAttribute("SendRequestFlag", flag);
		/// 发送信息 
		session.write(param1);
		/// 等待连接断开		
		session.getCloseFuture().awaitUninterruptibly();
		connector.dispose();
		
		//通过标识获取保存的结果
		Object result = ClientHandler.results.get(flag);
		//清除标识内容
		ClientHandler.results.remove(flag);
		//将结果返回客户端
		response.getWriter().write(result.toString());
	}

然后在mina客户端(车务通系统中接收),messageReceive()方责接收到消息时将系统全局唯一标识从Iosession中取出,将其和当前数据绑定保存,如:
	
public static final Map<String,Object> results = new ConcurrentHashMap<String,Object>();

public void messageReceived(IoSession session, Object message)			throws Exception {
  //从session中取到标识
  String flag = (String)session.getAttribute("SendRequestFlag");
  //将从服务端接收到的message和标识绑定保存,可以保存到内存、队列、文件、数据库等等
  //在这里简单的以标识为key,message为value保存到Map中
  results.put(flag, message);
  //关闭session
  session.close(true);
}


最后通过系统全局唯一标识获取结果并返回给客户端
		//通过标识获取保存的结果
		Object result = ClientHandler.results.get(flag);
		//清除标识内容
		ClientHandler.results.remove(flag);
		//将结果返回客户端
		response.getWriter().write(result.toString());


用servlet简单写了一个例子,以供参考,见附件。采用同步、异步调用均可,任君选择,在这例子中我采用jquery的ajax异步调用





你写的代码基本可以满足我的需求,不过有个问题,如果我只想建立一个连接来完成所有操作,而不是每次都新建连接,这个能实现吗?在你原有代码的基础上如何改动?谢谢
0 请登录后投票
   发表时间:2010-02-26   最后修改:2010-02-26
引用
你写的代码基本可以满足我的需求,不过有个问题,如果我只想建立一个连接来完成所有操作,而不是每次都新建连接,这个能实现吗?在你原有代码的基础上如何改动?谢谢

我写的只是一个简单的代码,以供参考,给你提示一下思路而己,你得根据你的项目使用情况进行修改。建立一个连接来完成所有操作可以实现。
0 请登录后投票
   发表时间:2010-02-26  
怎么保证

 //通过标识获取保存的结果  
    Object result = ClientHandler.results.get(flag);  


是在 messageReceived()后执行的?

0 请登录后投票
   发表时间:2010-02-26  
vvggsky 写道
怎么保证

 //通过标识获取保存的结果  
    Object result = ClientHandler.results.get(flag);  


是在 messageReceived()后执行的?


session.getCloseFuture().awaitUninterruptibly(); 
session.close(true); 
这两句话可以实现
是在 messageReceived()后执行的

不过就是需要断开连接  不知如何在不断开连接的情况下 实现触发
0 请登录后投票
   发表时间:2010-02-26  
leixm 写道
解决方法:一种是在mina的客户端写监听器,另一种是你应该在messageReceived中收到响应包后,重新获取请求句柄,做个回传!(handler中持有一个调用者的引用,当数据回来后,直接回传就行了)    要使用session.setattribute()一定要在使用完后坐清空操作,因为session.setAttribute实际上是把数据保持到了一个hashmap中. (还有不一定要使用mina啊,socket也可以噻!)




请问在mina客户端写监听,是用mina中原有的东西,还是自己写监听,如果是mina原有的东西,我在mina类库中没有找到相应的类,能不能给提示提示。

还有handle中的 请求句柄 也好像不存在 可能是自己没有找到 请提示
0 请登录后投票
   发表时间:2010-02-26  
leixm 写道
解决方法:一种是在mina的客户端写监听器,另一种是你应该在messageReceived中收到响应包后,重新获取请求句柄,做个回传!(handler中持有一个调用者的引用,当数据回来后,直接回传就行了)    要使用session.setattribute()一定要在使用完后坐清空操作,因为session.setAttribute实际上是把数据保持到了一个hashmap中. (还有不一定要使用mina啊,socket也可以噻!)




请问在mina客户端写监听,是用mina中原有的东西,还是自己写监听,如果是mina原有的东西,我在mina类库中没有找到相应的类,能不能给提示提示。

还有handle中的 请求句柄 也好像不存在 可能是自己没有找到 请提示
0 请登录后投票
   发表时间:2010-02-26  
C到S端一般都是TCP转HTTP,楼主这个流程应该是HTTP转TCP吧
0 请登录后投票
   发表时间:2010-02-26  
leixm 写道
解决方法:一种是在mina的客户端写监听器,另一种是你应该在messageReceived中收到响应包后,重新获取请求句柄,做个回传!(handler中持有一个调用者的引用,当数据回来后,直接回传就行了)    要使用session.setattribute()一定要在使用完后坐清空操作,因为session.setAttribute实际上是把数据保持到了一个hashmap中. (还有不一定要使用mina啊,socket也可以噻!)




请问在mina客户端写监听,是用mina中原有的东西,还是自己写监听,如果是mina原有的东西,我在mina类库中没有找到相应的类,能不能给提示提示。

还有handle中的 请求句柄 也好像不存在 可能是自己没有找到 请提示
0 请登录后投票
   发表时间:2010-02-26   最后修改:2010-02-26
lzp0070007 写道

请问在mina客户端写监听,是用mina中原有的东西,还是自己写监听,如果是mina原有的东西,我在mina类库中没有找到相应的类,能不能给提示提示。

还有handle中的 请求句柄 也好像不存在 可能是自己没有找到 请提示

这是一个监听的例子:
future.addListener(new IoFutureListener<ConnectFuture>() {
public void operationComplete(ConnectFuture future) {
IoSession session = future.getSession();
while (!session.isClosing()) {
try {
Thread.sleep(100);
String result=(String) session.getAttribute("resp");
if(result!=null){
System.out.println("传过来的值是:"+result);
session.removeAttribute("resp");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});



第二种中的请求句柄的意思就相当于你从数据库拿数据,只调用jdbc的executeQuery(sql)后,是不是要等待数据查询回来?这同样是的。在handler中持有一个调用者的引用,当数据回来后,直接回传就行了。

我昨天和别人讨论后觉得这种方式并不好,用阻塞/唤醒的方式是比较通用的方式。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics