2017-07-03 4 views
1

エラーメッセージ:プロトコルメッセージタグのワイヤタイプが無効です。 C#コードでPersonオブジェクトをシリアル化する必要がありますか?C#クライアントは、protobufを使用しているnettyサーバーを接続します

Mavenは

<dependencies> 
    <dependency> 
     <groupId>io.netty</groupId> 
     <artifactId>netty-all</artifactId> 
     <version>4.1.12.Final</version> 
    </dependency> 

    <dependency> 
     <groupId>com.google.protobuf</groupId> 
     <artifactId>protobuf-java</artifactId> 
     <version>3.3.1</version> 
    </dependency> 

    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

サーバコード

public class AppServer { 
    public void startSocket(int port) throws Exception { 
    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 

    try { 
     ServerBootstrap serverBootstrap = new ServerBootstrap(); 
     serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 
       .option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)) 
       .childHandler(new ChannelInitializer<SocketChannel>() { 

        @Override 
        protected void initChannel(SocketChannel ch) throws Exception { 
         ch.pipeline().addLast(new ProtobufVarint32FrameDecoder()); 
         ch.pipeline().addLast(new ProtobufDecoder(Person.getDefaultInstance())); 
         ch.pipeline().addLast(new ProtobufServerHandler()); 

        } 
       }); 
     ChannelFuture future = serverBootstrap.bind(port).sync(); 
     System.out.println("Server Starting."); 
     future.channel().closeFuture().sync(); 
    } finally { 
     bossGroup.shutdownGracefully(); 
     workerGroup.shutdownGracefully(); 
    } 
} 

public static class ProtobufServerHandler extends ChannelInboundHandlerAdapter { 
    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
     Person person = (Person) msg; 
     System.out.println(person); 
    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
     // TODO Auto-generated method stub 
     super.channelReadComplete(ctx); 
    } 

    @Override 
    public void channelActive(ChannelHandlerContext ctx) throws Exception { 
     super.channelActive(ctx); 
     Person john = Person.newBuilder().setId(1234).setName("John Doe").setEmail("[email protected]") 
       .addPhones(Person.PhoneNumber.newBuilder().setNumber("555-4321").setType(Person.PhoneType.HOME)) 
       .build(); 
     ctx.writeAndFlush(john); 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
     cause.printStackTrace(); 
    } 
} 

public static void main(String[] args) throws Exception { 
    int port = 8081; 

    if(args != null && args.length > 0){ 
     port = Integer.valueOf(args[0]); 
    } 

    new AppServer().startSocket(port); 
    } 
} 

C#クライアントコード

namespace proto 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     socket.Connect("127.0.0.1", 8081); 
     Console.WriteLine("===========connect to server==========="); 

     var buffer = new byte[1024 * 1024]; 
     socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); 

     SendMessage(socket); 

     if (socket.Connected) 
     { 
      socket.Shutdown(SocketShutdown.Both); 
     } 


     Console.Read(); 
    } 

      private static void SendMessage(Socket socket) 
    { 
     var sam = new Person(); 
     sam.Name = "John Doe"; 
     sam.Email = "[email protected]"; 
     sam.Id = 1234; 
     sam.Phones.Add(new Person.Types.PhoneNumber() 
     { 
      Number = "555-4321", 
      Type = Person.Types.PhoneType.Home 
     }); 

     if (socket.Connected) 
     { 
      var stream = new MemoryStream(); 
      var aa = sam.ToByteArray(); 

      socket.BeginSend(aa, 0, aa.Length, SocketFlags.None, null, null);     
     } 
    } 

    private static void ReceiveMessage(IAsyncResult ar) 
    { 
     Console.WriteLine("===========receive from server==========="); 
     Console.WriteLine(ar); 
    } 
} 
    } 

.protoファイル

// See README.txt for information and build instructions. 
    // 
    // Note: START and END tags are used in comments to define sections used in 
    // tutorials. They are not part of the syntax for Protocol Buffers. 
    // 
    // To get an in-depth walkthrough of this file and the related examples, see: 
    // https://developers.google.com/protocol-buffers/docs/tutorials 

    // [START declaration] 
    syntax = "proto3"; 
    package tutorial; 
    // [END declaration] 

    // [START java_declaration] 
    option java_package = "com.example.tutorial"; 
    option java_outer_classname = "AddressBookProtos"; 
    // [END java_declaration] 

    // [START csharp_declaration] 
    option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; 
    // [END csharp_declaration] 

    // [START messages] 
    message Person { 
    string name = 1; 
    int32 id = 2; // Unique ID number for this person. 
    string email = 3; 

    enum PhoneType { 
     MOBILE = 0; 
     HOME = 1; 
     WORK = 2; 
    } 

    message PhoneNumber { 
     string number = 1; 
     PhoneType type = 2; 
    } 

    repeated PhoneNumber phones = 4; 
    } 

    // Our address book file is just one of these. 
    message AddressBook { 
    repeated Person people = 1; 
    } 
    // [END messages] 
を設定します

エラーが発生しました:プロトコルメッセージタグのワイヤタイプが無効です。私のC#コードは、Personオブジェクトを直列化する必要がありますか?

答えて

0

サーバーコードでは、可変長ベースのフレームデコーダ(ProtobufVarint32FrameDecoder)の言及があります。おそらく、長さプレフィックス付きメッセージ(フレーム)を予期しています。しかし、あなたのクライアントコードはフレーミングメカニズムなしで生のprotobufを送ります。

クライアントコードにフレームを追加する必要があります(これはprotobuf-netの場合はSerializeWithLengthPrefixメソッドになります)。

関連する問題