怎么非响应式的主动调用mina发送消息

颖辉小居 发布于 2016/01/09 19:23
阅读 930
收藏 0
有两个服务器 一个javaWeb(tomcat+ssh框架 由我开发)服务器 一个C++服务器(其他公司的)。javaweb为手机APP提供服务。当有手机用户通过APP发送请求时,JavaWeb处理业务以后要发送给C++一条消息。java使用Mina框架和C++交互。请问怎么能在javaWeb收到手机端消息时 由service层来主动触发mina发送消息给c++。
加载中
1
你是错的我恒对
你是错的我恒对

非响应是啥意思啊?

随便说两句哈,没太理解lz意思

1.javaweb  跟mina交互系统是一个系统?service层直接调用mina发消息就可以啊

2.javaweb跟mina交互是两个系统?那就是两个java同构系统通信问题了,可以http也可以rpc也可以消息

3.javaweb 跟c++异构交互系统没有构建,用mina构建起通信,协议可以用thrift  protobuf 什么的然后后面操作同上1,2

你是错的我恒对
你是错的我恒对
回复 @颖辉小居 : 调用write线程安全与否,我不知道,我看看代码找到答案在告诉你。但我猜测很可能是线程安全的,mina没用过,我以前用过netty,netty带了很多解码器,可以正确拆分包,client是线程安全的。然后假如你想要的是双向通信,就是发送完要拿到结果那种,那需要自己控制多线程问题了,一般请求时候带个ID,response里反回ID, 跟据ID 对应到相应线程
颖辉小居
颖辉小居
回复 @water12 : 您的意思是吧 IOsession 设置为静态对吗?这样外部调用他会不会线程 不安全啊
你是错的我恒对
你是错的我恒对
回复 @颖辉小居 : 把mina内嵌到java web客户端系统,把mina跟c++建立的链接保存为static,采用长连接方式,我只能帮到这了,亲 - -|
颖辉小居
颖辉小居
回复 @颖辉小居 : 请问怎么在service层调用mina啊??着急啊
颖辉小居
颖辉小居
回复 @water12 : 没有项目经理,都交给我自己了。
下一页
0
颖辉小居
颖辉小居
自己顶 求助
0
szf
szf

ConnectFuture 对象的 getSession, 得到IoSession就可以使用Write了。

当然,CF对象的状态,Write时关联的Handler和Encode类, 都要保证正确才行。

颖辉小居
颖辉小居
回复 @szf : 请问有例子吗?
颖辉小居
颖辉小居
回复 @szf :项目的情况是这样的,javaweb的客户端有两种一种是手机app 一种是C++客户端。和手机APP用的是struts2框架基于http协议。和C++交互是计划使用mina框架。但是给C++什么时候发发什么?受到手机APP请求所影响。手机aPP的业务处理在action和service层。这里怎么调用mina发送消息给C++呢?
szf
szf
回复 @颖辉小居 : 这句其实有点废话了,其实你既然会用mina,那么codec和handler这些想必已经都OK了的。 IoSession发送时,数据是会经过encode类处理的,所以提了一下。
颖辉小居
颖辉小居
您好 “CF对象的状态,Write时关联的Handler和Encode类, 都要保证正确才行。”这句话我没明白啊,什么意思啊?
0
szf
szf

举个例子,作为客户端,SocketConnector 发起连接时,connect()函数会返回一个ConnectFuture对象,通过这个对象可判断是否已经连接,如果已经连接的话,通过它获取IoSession对象,就可以Write了。

随时Write就是主动发送了。

颖辉小居
颖辉小居
我是 用 IoAcceptor acceptor = new NioSocketAcceptor(); 来启动监听的。怎么能在handle外面获得IOsession呢?
颖辉小居
颖辉小居
请看下面我引用您的话发的代码
0
颖辉小居
颖辉小居

引用来自“szf”的评论

举个例子,作为客户端,SocketConnector 发起连接时,connect()函数会返回一个ConnectFuture对象,通过这个对象可判断是否已经连接,如果已经连接的话,通过它获取IoSession对象,就可以Write了。

随时Write就是主动发送了。

我的服务端类似这样的,怎么可以获得IOSeesion 并将其静态化供外部调用呢?不在这个类里用。在javaweb的service层直接调用这个连接发送消息

package mina.PrefixedStringCodec;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class TcpServer {
	public static void main(String[] args) throws IOException {  
        IoAcceptor acceptor = new NioSocketAcceptor();  
          
        // 4字节的Header指定Body的字节数,对这种消息的处理  
        acceptor.getFilterChain().addLast("codec",   
                new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));  
          
        acceptor.setHandler(new TcpServerHandle());  
        acceptor.bind(new InetSocketAddress(8888));  
    }  
  
}  
  
class TcpServerHandle extends IoHandlerAdapter {  
  
    //@Override  
    public void exceptionCaught(IoSession session, Throwable cause)  
            throws Exception {  
        cause.printStackTrace();  
    }  
  
    // 接收到新的数据  
    //@Override  
    public void messageReceived(IoSession session, Object message)  
            throws Exception {  
  
        String msg = (String) message;  
        System.out.println("messageReceived:" + msg);  
          
    }  
  
    //@Override  
    public void sessionCreated(IoSession session) throws Exception {  
        System.out.println("sessionCreated");  
    }  
  
    //@Override  
    public void sessionClosed(IoSession session) throws Exception {  
        System.out.println("sessionClosed");  
    }  
}



0
你是错的我恒对
你是错的我恒对
 

write 也是线程安全的,每一个netty的channel是有一个writelock的,看了个大概,不是太透彻。

注:提个建议哈,我觉得lz先写代码,多看文档,多思考下,可以自己解决的,再说问问题很不靠谱,没人回答很正常,有人回答跟中彩票似的

private void write0(NioSocketChannel channel) {
        boolean open = true;
        boolean addOpWrite = false;
        boolean removeOpWrite = false;

        long writtenBytes = 0;

        final SocketSendBufferPool sendBufferPool = this.sendBufferPool;
        final SocketChannel ch = channel.socket;
        final Queue<MessageEvent> writeBuffer = channel.writeBuffer;
        final int writeSpinCount = channel.getConfig().getWriteSpinCount();
        synchronized (channel.writeLock) {
            channel.inWriteNowLoop = true;
            for (;;) {



0
szf
szf

引用来自“szf”的评论

举个例子,作为客户端,SocketConnector 发起连接时,connect()函数会返回一个ConnectFuture对象,通过这个对象可判断是否已经连接,如果已经连接的话,通过它获取IoSession对象,就可以Write了。

随时Write就是主动发送了。

引用来自“颖辉小居”的评论

我的服务端类似这样的,怎么可以获得IOSeesion 并将其静态化供外部调用呢?不在这个类里用。在javaweb的service层直接调用这个连接发送消息

package mina.PrefixedStringCodec;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class TcpServer {
	public static void main(String[] args) throws IOException {  
        IoAcceptor acceptor = new NioSocketAcceptor();  
          
        // 4字节的Header指定Body的字节数,对这种消息的处理  
        acceptor.getFilterChain().addLast("codec",   
                new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));  
          
        acceptor.setHandler(new TcpServerHandle());  
        acceptor.bind(new InetSocketAddress(8888));  
    }  
  
}  
  
class TcpServerHandle extends IoHandlerAdapter {  
  
    //@Override  
    public void exceptionCaught(IoSession session, Throwable cause)  
            throws Exception {  
        cause.printStackTrace();  
    }  
  
    // 接收到新的数据  
    //@Override  
    public void messageReceived(IoSession session, Object message)  
            throws Exception {  
  
        String msg = (String) message;  
        System.out.println("messageReceived:" + msg);  
          
    }  
  
    //@Override  
    public void sessionCreated(IoSession session) throws Exception {  
        System.out.println("sessionCreated");  
    }  
  
    //@Override  
    public void sessionClosed(IoSession session) throws Exception {  
        System.out.println("sessionClosed");  
    }  
}



Server端更简单啊,

public void sessionCreated(IoSession session) throws Exception {  
        System.out.println("sessionCreated");  
    }
这里的session就已经是可以发包的对象了,直接调用它的write就是了。

当然,你得在这个响应事件中把它的引用在其它地方保存下来,也要在它Close时把其它地方的引用除掉。

szf
szf
回复 @颖辉小居 : 晕倒,这还要代码? 你定义个全局变量(App级别的)如appsession,然后在sessionCreated事件中,appsession = session; 然后在其它地方调用appsession.write(object);
颖辉小居
颖辉小居
我的意思是在这个handler外面比如同一个项目中javaWeb struts2框架的action里调用发送。在javaWeb收到手机APP客户端发送请求的时候通过mina框架将这个请求再发送到C++的服务器(这个C++相当于mina客户端)
返回顶部
顶部