开发一个自己的quic sdk

    一、首先,我们要做的是继承QuicStream 和  QuicSession 并实现其虚函数。

    QuicStream中必须要实现的接口是数据回调接口,如下:

  // Called when new data is available from the sequencer.  Subclasses must
  // actively retrieve the data using the sequencer's Readv() or
  // GetReadableRegions() method.
  virtual void OnDataAvailable() = 0;

    而QuicSession中必须要实现的接口则比较多,如下:

  // Creates a new stream to handle a peer-initiated stream.
  // Caller does not own the returned stream.
  // Returns nullptr and does error handling if the stream can not be created.
  virtual QuicStream* CreateIncomingDynamicStream(QuicStreamId id) = 0;

  // Create a new stream to handle a locally-initiated stream.
  // Caller does not own the returned stream.
  // Returns nullptr if max streams have already been opened.
  virtual QuicStream* CreateOutgoingDynamicStream(uint8_t priority) = 0;

  // Return the reserved crypto stream.
  virtual QuicCryptoStream* GetMutableCryptoStream() = 0;

  // Return the reserved crypto stream as a constant pointer.
  virtual const QuicCryptoStream* GetCryptoStream() const = 0;
  // Unconditionally creates a stream.  Subclasses should use this to
  // provide streams appropriately subclassed from |QuicStream|,
  // e.g. |QuicSpdySession::CreateStream()| creates a |QuicSpdyStream|.
  virtual std::unique_ptr CreateStream(QuicStreamId id) = 0;

二、构建外部调用的接口,包括创建及初始化Session、通过session连接远端服务、创建Stream。

    为了连接远端服务,我们需要使用一个加密流,即流ID为1。连接远端即发送握手信息,握手成功即为连接远端成功。

    为了创建的Stream类型是自己实现的Stream类,需要在session中增加CreateStream接口,在该实现中创建stream类对象。

  void InitializeSession(const QuicServerId& server_id,
                         QuicCryptoClientConfig* config);
  
  bool CryptoConnect();

  QuicClientStream* CreateClientStream(QuicConnectionHelperInterface* helper,
                          QuicAlarmFactory* alarm_factory, StreamVisitor*);
  QuicClientStream* CreateClientStream(QuicConnectionHelperInterface* helper,
                          QuicAlarmFactory* alarm_factory, void(*fun)(void*, size_t, void*), void*);

三、具体代码如下:

client/quic_client_session.h

#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_
#define NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_

#include 

#include "net/quic/core/crypto/quic_crypto_client_config.h"
#include "net/quic/core/quic_crypto_client_stream.h"
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/quic_session.h"
#include "net/quic/core/quic_server_id.h"
#include "net/quic/core/quic_config.h"
#include "google/protobuf/stubs/scoped_ptr.h"
using namespace google::protobuf;
using namespace net;

class QuicClientStream;
class StreamVisitor;

class QuicClientSession : 
    public QuicSession,
    public QuicCryptoClientStream::ProofHandler,
	public QuicSession::Visitor
    {
 public:
  QuicClientSession(const QuicConfig& config, QuicConnection* connection, QuicSession::Visitor* vistor);
  ~QuicClientSession() override;

  void InitializeSession(const QuicServerId& server_id,
                         QuicCryptoClientConfig* config);
  
  bool CryptoConnect();

  QuicClientStream* CreateClientStream(QuicConnectionHelperInterface* helper,
                          QuicAlarmFactory* alarm_factory, StreamVisitor*);
  QuicClientStream* CreateClientStream(QuicConnectionHelperInterface* helper,
                          QuicAlarmFactory* alarm_factory, void(*fun)(void*, size_t, void*), void*);

  /*---------------------openssl certification*/
  virtual void OnProofValid (const QuicCryptoClientConfig::CachedState& cached) override {};
  virtual void OnProofVerifyDetailsAvailable (const ProofVerifyDetails& verify_details) override {};


  /*---------------------QuicSession */
  virtual QuicStream* CreateOutgoingDynamicStream(SpdyPriority priority) { return nullptr; };
  virtual QuicStream* CreateIncomingDynamicStream(QuicStreamId id) { return nullptr; };

  virtual QuicCryptoStream* GetMutableCryptoStream() override { return crypto_stream_.get(); };
  virtual const QuicCryptoStream* GetCryptoStream() const override { return crypto_stream_.get(); };

  virtual std::unique_ptr CreateStream(QuicStreamId id) { return nullptr; }

  /*---------------------QuicSession::Visitor */
  virtual void OnConnectionClosed(QuicConnectionId conneciton_id, 
	  QuicErrorCode err, const std::string& code_details) override;
  virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
  virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;

 private:
  scoped_ptr crypto_stream_; 

};


#endif  // NET_TOOLS_QUIC_QUIC_CLIENT_SESSION_H_

client/quic_client_session.cc

#include "client/quic_client_session.h"
#include "client/quic_client_stream.h"

QuicClientSession::QuicClientSession(const QuicConfig& config,
                                     QuicConnection* connection, QuicSession::Visitor* visitor)
    : QuicSession(connection, (visitor==NULL)?NULL:visitor/*mybe 'this' can be better */,config) {
}

QuicClientSession::~QuicClientSession() {
}

void QuicClientSession::InitializeSession(
    const QuicServerId& server_id,
    QuicCryptoClientConfig* crypto_config) {
  crypto_stream_.reset(
      new QuicCryptoClientStream(server_id, this, nullptr, crypto_config, this));
  QuicSession::Initialize();
}

bool QuicClientSession::CryptoConnect() {
  DCHECK(flow_controller());
  return crypto_stream_->CryptoConnect();
}
  
QuicClientStream* QuicClientSession::CreateClientStream(
        QuicConnectionHelperInterface* helper,
        QuicAlarmFactory* alarm_factory, StreamVisitor* visitor) {
  QuicStream* stream = new QuicClientStream(GetNextOutgoingStreamId(), this, helper, alarm_factory, visitor);
  ActivateStream(std::unique_ptr(stream));
  return (QuicClientStream*) stream;
}

QuicClientStream* QuicClientSession::CreateClientStream(
        QuicConnectionHelperInterface* helper,
        QuicAlarmFactory* alarm_factory,
        void(*fun)(void*, size_t, void*), void* arg)
{
    QuicStream* stream = new QuicClientStream(GetNextOutgoingStreamId(), this, helper,alarm_factory, fun, arg);
    ActivateStream(std::unique_ptr(stream));
    return (QuicClientStream*) stream;
}


    


你可能感兴趣的:(QUIC)