ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 클라이언트와 c++ 서버 플랫 버퍼로 통신하기 성공~
    프로그래밍/의문 2017. 12. 4. 22:10
    반응형

    c++ 서버는 boost/asio 기반으로 만들었다.


    #include <iostream>
    #include <iterator>
    #include <nta/tcp.hpp>
    #include "packets.h"

    class flatbuffers_filter : public nta::receive_filter // 아직 작성되지 않음
    {
    public:
    virtual result feed(const std::byte* data, std::size_t size) {
    return drain(size);
    }
    };

    class session : public nta::tcp::session
    {
    public:

    session(nta::tcp::session_params params) :
    nta::tcp::session(std::move(params))
    {
    }

    virtual void on_opened() override
    {
    std::cout << "opened" << std::endl;
    flatbuffers::FlatBufferBuilder builder;
    builder.Finish(MyGames::packet::CreateVector2(builder, 10.0f, 10.0f));
    auto data = builder.GetBufferPointer();
    auto size = builder.GetSize();
    std::vector<char> buffer(sizeof(packet::header) + size);
    packet::header header{ 0, size };
    std::memcpy(buffer.data(), &header, sizeof(header));
    this->send(buffer.data(), buffer.size());
    }

    virtual void on_closed() override
    {
    }

    virtual void on_received(const std::error_code& err, const nta::packet& packet) override
    {
    if (err)
    this->close();
    }

    virtual void on_sent(const std::error_code &) override
    {
    }

    };

    int main(){
    nta::tcp::server_builder builder;
    builder
    .endpoint("localhost:16333")
    .max_sessions(1)
    .session <session>();
    std::shared_ptr<nta::tcp::server> server = builder.build();
    server->run();
    return 0;
    }


    유니티 클라이언트는 c#을 이용해서 만들었다.


    플랫 버퍼의 총 크기는 알 수 없으므로 패킷 헤더에 타입과 사이즈를 넣었다. 헤더의 사이즈엔 플랫버퍼의 크기가 기록된다.


    받은 데이터가 헤더를 제외하고 헤더에 명시된 플랫버퍼 크기 이상을 받았다면 그만큼 잘라서 쓰면 된다.

    type은 플랫버퍼를 바이너리를 역직렬화 할 때 어떤 변환을 거칠 것인지 판단을 할 기준이 있어야 하기 때문에 반드시 필요하다.

    using System.Collections.Generic;
    using UnityEngine;
    using Assets;
    using System.Net;
    using FlatBuffers;

    public class GameController : MonoBehaviour {

      RemoteServer server;
      HashSet<GameObject> objects = new HashSet<GameObject>();

      // Use this for initialization
      void Start ()
    {
        server = new RemoteServer(new IPEndPoint(IPAddress.Loopback, 16333), (int type, byte[] body)=>
        {
          switch(type)
          {
            case 0:
              {// 타입 0이면 Vector2로 변환하는 처리!
                var vec2 = MyGames.packet.Vector2.GetRootAsVector2(new ByteBuffer(body));
                Debug.Log(string.Format("{0} {1}", vec2.X, vec2.Y));
              }
              break;
          }
          
        });
        server.Start();
      }

      void Update ()
    {
        server.Update();
      }
    }


    접속하면 c++ 서버에서 10, 10을 보내고 유니티 클라이언트에서 10, 10을 받았다. 많이 다듬어야겠지만 물꼬는 틀었다 ~_~ 


    반응형
Designed by Tistory.