0
Server

import java.util.concurrent.atomic.AtomicReference;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.spdy.DefaultSpdySynStreamFrame;

public class SpdyChannelUpStreamHandler extends SimpleChannelUpstreamHandler {
volatile Channel channel;
final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();

@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
        throws Exception {
    System.out.println("Channel In Open Stage");
    channel = e.getChannel();

}

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
        throws Exception {
    System.out.println("Channel In Connected Stage");
    Channels.write(channel, new DefaultSpdySynStreamFrame(1, 1, (byte)0));
}

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
        throws Exception {
    System.out.println("Message Received on Server Side");
     Channels.write(channel, e.getMessage(), e.getRemoteAddress());
}


@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
        throws Exception {
     if (exception.compareAndSet(null, e.getCause())) {
         e.getChannel().close();
     }
}

}

import static org.jboss.netty.channel.Channels.pipeline;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.spdy.SpdyFrameDecoder;
import org.jboss.netty.handler.codec.spdy.SpdyFrameEncoder;
import org.jboss.netty.handler.codec.spdy.SpdySessionHandler;

public class SpdyPipeLineFactory implements ChannelPipelineFactory{

@Override
public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline pipeline = pipeline();
    pipeline.addLast("decoder", new SpdyFrameDecoder(2));
    pipeline.addLast("encoder", new SpdyFrameEncoder(2));
    //pipeline.addLast("sessionHandler",new SpdySessionHandler(2,true));
    pipeline.addLast("handler", new SpdyChannelUpStreamHandler());
    return pipeline;
}

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 StartServer {
public static void main(String[] args){
ServerBootstrap bootStrapServer = new ServerBootstrap(new 
        NioServerSocketChannelFactory(Executors.newCachedThreadPool(), 
        Executors.newCachedThreadPool()));
    bootStrapServer.setPipelineFactory(new SpdyPipeLineFactory());
    bootStrapServer.bind(new InetSocketAddress(8443));
}


}

これは、インターネット上の複数の場所で読んで netty ライブラリを使用してまとめることができた SPDY 対応サーバーの例です。このサーバーを実行し、SPDY クライアントを使用して接続すると、channelOpen と channelConnected という関数でメッセージが表示されるため、接続は成功します。

SPDY プロトコルの理解が非常に限られているため、質問したいことがいくつかあります。まずはやりたいことから始めます。

1 - サーバーはどのようにクライアントにメッセージを送信できますか?

SPDY サーバーで現在開いているすべてのチャネルへのハンドルを取得し、これらのチャネルを特定して、オンデマンドでチャネルを選択し、それらを使用してメッセージを送信できるようにする方法はありますか?

4

1 に答える 1

0

最善の策は、共有 ChannelGroup を作成し、新しいチャネルが接続されるたびにチャネルを ChannelGroup に追加することです。利用可能なチャネル メタデータ (リモート アドレスやチャネル ID など) に基づいて、送信先のチャネルを識別する方法を理解する必要があります。その後、ChannelGroup からチャネルを取得し、メッセージを書き込むことができます。ChannelGroup のその他の利点は次のとおりです。

  • チャネルが閉じられると、ChannelGroup から自動的に削除されます。
  • ChannelGroup で close を呼び出して、含まれているすべてのチャネルを閉じることができます。
  • ChannelGroup で書き込みを呼び出して、含まれているすべてのチャネルにメッセージを書き込むことができます。

追加のメタデータをチャネルに関連付けることができるように、拡張チャネル ラッパーを作成しました。私のプロトコルの一部は、新しいチャネルが接続されたときに WHO メッセージを送信し、クライアントがチャネル ラッパーに追加するいくつかのクライアント ID 値で応答することです。また、グループ内のチャネルを公開する JMX インターフェースも実装したので、どのクライアントが接続されているかを正確に確認できます。

JConsole の拡張チャネル メタデータのスクリーン ショット

于 2012-12-06T14:34:33.600 に答える