Class: Mongo::Protocol::Message Abstract

继承:
对象
  • 对象
显示全部
包括:
ID ,序列化器
定义于:
lib/ Mongo/ 协议/message.rb

Overview

此类是抽象类。

提供MongoDB传输协议中所有消息所需功能的基类。 它提供了用于定义类型化字段的最小 DSL,以启用通过网络进行序列化和反序列化。

例子:

class WireProtocolMessage < Message

  private

  def op_code
    1234
  end

  FLAGS = [:first_bit, :bit_two]

  # payload
  field :flags, BitVector.new(FLAGS)
  field :namespace, CString
  field :document, Document
  field :documents, Document, true
end

直接已知子类

CompressedGetMoreKillCursorsMsgQueryReply

常量摘要折叠

BATCH_SIZE =

批处理大小常量。

由于:

  • 2.2.0

'batchSize'
集合 =

集合常量。

由于:

  • 2.2.0

'集合'
LIMIT =

极限常量。

由于:

  • 2.2.0

'limit'
ORDERED =

有序常量。

由于:

  • 2.2.0

'ordered'
Q =

q 常量。

由于:

  • 2.2.0

'q'
MAX_MESSAGE_SIZE =

默认最大消息大小为48 MB。

由于:

  • 2.2.1

50_331_648

序列化器中包含的常量

Serializers::HEADER_PACKSerializers::INT32_PACKSerializers::INT64_PACKSerializers::NULLSerializers::ZERO

实例属性摘要折叠

类方法摘要折叠

实例方法摘要折叠

ID中包含的方法

包含

构造函数详情

#initialize(*_args) ⇒ 消息

:nodoc:



77
78
79
# File 'lib/ Mongo/ 协议/message.rb', line 77

def 初始化(*_args) # :nodoc:
  set_request_id
end

实例属性详细信息

# request_id =" Fixnum " (只读)

返回消息的请求 ID

返回:

  • (Fixnum)

    此消息的请求ID



84
85
86
# File 'lib/ Mongo/ 协议/message.rb', line 84

def request_id
  @request_id
end

类方法详细信息

deserialize (io, max_message_size = MAX_MESSAGE_SIZE,expected_response_to = nil, options = {}) ⇒消息

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

反序列化来自 IO 流的消息。

该方法返回解压缩的消息(即,如果传输的消息是 OP_COMPRESSED,则该方法通常会返回作为解压缩结果的 OP_MSG 消息)。

参数:

  • max_message_size 整数 (默认为: MAX_MESSAGE_SIZE

    最大消息大小。

  • io ( IO )

    包含消息的流

  • 选项 哈希 (默认为: {}

选项哈希 ( options ):

  • :deserialize_as_bson 布尔值

    是否尽可能使用BSON types而不是原生Ruby类型来反序列化此消息。

  • :socket_timeout 数字

    用于每个读取操作的超时时间。

返回:

  • (消息)

    Message 类的实例

引发:



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/ Mongo/ 协议/message.rb', line 235

def self.反序列化(io,
                     max_message_size = MAX_MESSAGE_SIZE,
                     expired_response_to = nil,
                     选项 = {})
  # io 通常是一个 Mongo::Socket实例,它支持
  # 超时选项。 为了与可能调用此
  # 具有其他类似 IO对象的方法,仅当它们
  # 不为空。
  read_options = 选项.slice(:timeout, :socket_timeout)

  数据段 = if read_options.空?
            io.(16)
          else
            io.(16, **read_options)
          end
  buf = BSON::ByteBuffer.new(数据段)
  长度, _request_id, response_to, _op_code = deserialize_header(buf)

  # 防止潜在的 DOS 中间人攻击。 请参阅
  # DRIVERS- 276 。
  提高 错误::MaxMessageSize.new(max_message_size) if 长度 > (max_message_size || MAX_MESSAGE_SIZE)

  # 防止返回对先前请求的响应。 请参阅
  # RUBY- 1117
  if expired_response_to && response_to != expired_response_to
    提高 错误::UnexpectedResponse.new(expired_response_to, response_to)
  end

  数据段 = if read_options.空?
            io.(长度 - 16)
          else
            io.(长度 - 16, **read_options)
          end
  buf = BSON::ByteBuffer.new(数据段)

  message = 注册表.获取(_op_code).分配
  message.发送(:fields). do |字段|
    if 字段[:multi]
      deserialize_array(message, buf, 字段, 选项)
    else
      deserialize_field(message, buf, 字段, 选项)
    end
  end
  message.fix_after_deserialization if message.is_a?(消息)
  message.也许_inflate
end

deserialize_array (message, io, 字段, options = {}) ⇒ 消息

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

反序列化消息中的字段数组

数组中的项目数必须由先前反序列化的字段来描述,该字段由键下的字段dsl在类中指定 :multi

参数:

  • message (消息)

    包含反序列化数组的消息。

  • io ( IO )

    包含要反序列化的数组的流。

  • 字段 (哈希)

    表示字段的哈希。

  • 选项 哈希 (默认为: {}

选项哈希 ( options ):

  • :deserialize_as_bson 布尔值

    是否尽可能使用BSON 类型反序列化此数组中的每个元素。

返回:

  • (消息)

    包含反序列化数组的消息。



382
383
384
385
386
387
# File 'lib/ Mongo/ 协议/message.rb', line 382

def self.deserialize_array(message, io, 字段, 选项 = {})
  元素 = []
  数数 = message.instance_variable_get(字段[:multi])
  数数. { 元素 << 字段[:type].反序列化(io, 选项) }
  message.instance_variable_set(字段[:name], 元素)
end

deserialize_field (message, io, 字段, options = {}) ⇒ 消息

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

反序列化消息中的单个字段

参数:

  • message (消息)

    包含反序列化字段的消息。

  • io ( IO )

    包含要反序列化的字段的流。

  • 字段 (哈希)

    表示字段的哈希。

  • 选项 哈希 (默认为: {}

选项哈希 ( options ):

  • :deserialize_as_bson 布尔值

    是否尽可能使用BSON 类型反序列化该字段。

返回:

  • (消息)

    带有反序列化字段的消息。



401
402
403
404
405
406
# File 'lib/ Mongo/ 协议/message.rb', line 401

def self.deserialize_field(message, io, 字段, 选项 = {})
  message.instance_variable_set(
    字段[:name],
    字段[:type].反序列化(io, 选项)
  )
end

deserialize_header(io) ⇒ 数组<Fixnum>

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

反序列化消息头

参数:

  • io ( IO )

    包含标头的流。

返回:

  • ( Array<Fixnum> )

    反序列化的标头。



336
337
338
# File 'lib/ Mongo/ 协议/message.rb', line 336

def self.deserialize_header(io)
  标头.反序列化(io)
end

字段(name, type, multi = false) ⇒ NilClass

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

一种声明消息字段的方法

参数:

  • 名称 ( string )

    字段名称

  • 类型 (模块)

    特定于类型的序列化策略

  • truefalseSymbol (默认为: false

    指定为 true 可将字段值序列化为类型为 :type 的数组,或描述为具有数组中字段数的字段的符号(在反序列化时使用)

    Note: In fields where multi is a symbol representing the field
    containing number items in the repetition, the field containing
    that information *must* be deserialized prior to deserializing
    fields that use the number.

返回:

  • (NilClass)


356
357
358
359
360
361
362
363
364
# File 'lib/ Mongo/ 协议/message.rb', line 356

def self.字段(名称, 类型,  = false)
  字段 << {
    名称: :"@#{名称}",
    类型: 类型,
    multi: 
  }

  attr_reader 名称
end

字段整数

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

用于获取消息类字段的类方法

返回:

  • ( Integer )

    消息类的字段



327
328
329
# File 'lib/ Mongo/ 协议/message.rb', line 327

def self.字段
  @fields ||= []
end

实例方法详细信息

# == (other) ⇒ true , false也称为: eql?

通过比较类和字段值来测试两个传输协议消息之间的相等性。

参数:

返回:

  • ( true , false )

    消息的相等性。



287
288
289
290
291
292
293
294
295
# File 'lib/ Mongo/ 协议/message.rb', line 287

def ==(其他)
  return false if self.class != 其他.class

  字段.全部? do |字段|
    名称 = 字段[:name]
    instance_variable_get(名称) ==
      其他.instance_variable_get(名称)
  end
end

# hash =" Fixnum "

根据消息字段的值创建哈希。

返回:

  • (Fixnum)

    消息的哈希代码。



301
302
303
# File 'lib/ Mongo/ 协议/message.rb', line 301

def 哈希
  字段.map { |字段| instance_variable_get(字段[:name]) }.哈希
end

#也许_add_server_api (server_api) ⇒对象

支持服务器API 选项的协议消息子类应重写此方法,以将服务器API文档添加到消息中。

参数:

  • server_api (哈希)

    要添加到消息的服务器API文档。

引发:

  • ( NotImplementedError )


175
176
177
# File 'lib/ Mongo/ 协议/message.rb', line 175

def 也许_add_server_api(server_api)
  提高 NotImplementedError
end

#maybe_compress (_compressor, _zlib_compression_level = nil) ⇒ self

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

如果所使用的传输协议支持并且发送的命令允许压缩,则压缩消息。 否则返回 self。

参数:

  • 压缩器 ( string , Symbol )

    要使用的压缩程序。

  • zlib_compression_level ( Integer )

    要使用的zlib压缩级别。

返回:

  • ( self )

    始终返回自身。 其他消息类型应重写此方法。

由于:

  • 2.5.0



110
111
112
# File 'lib/ Mongo/ 协议/message.rb', line 110

def 也许_压缩(_compressor, 压缩 = nil)
  self
end

#maybe_decrypt(_context) ⇒ Mongo::协议::Msg

可能使用 libmongocrypt 解密此消息。

参数:

返回:

  • (Mongo::Protocol::Msg)

    解密后的消息,如果无法或无需解密,则为原始消息。



150
151
152
153
154
155
156
# File 'lib/ Mongo/ 协议/message.rb', line 150

def Maybe_decrypt(_context)
  # TODO: 确定我们是否应该解密来自 4.2 之前版本的数据
  # 个服务器,可能使用传统传输协议。 如果是这样,我们需要
  # 对这些传输协议实现解密,因为我们当前
  # 加密/解密代码特定于 OP_MSG。
  self
end

#maybe_encrypt(_connection, _context) ⇒ Mongo::协议::Msg

可以使用 libmongocrypt 加密此消息。

参数:

返回:

  • (Mongo::Protocol::Msg)

    加密的消息,如果不可能或不需要加密,则为原始消息。



166
167
168
169
# File 'lib/ Mongo/ 协议/message.rb', line 166

def 也许_加密(_connection, _context)
  # 如果 Message 子类未实现此方法,则不执行任何操作
  self
end

#也许_inflateProtocol::Message

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

如果消息被压缩,则对消息进行扩充。

返回:

  • (Protocol::Message)

    始终返回自身。 子类应根据需要重写此方法。

由于:

  • 2.5.0



140
141
142
# File 'lib/ Mongo/ 协议/message.rb', line 140

def 也许_inflate
  self
end

# number_returned0

协议消息的默认返回值。

返回:

  • ( 0 )

    必须重写此方法,否则始终返回0 。

由于:

  • 2.5.0



319
320
321
# File 'lib/ Mongo/ 协议/message.rb', line 319

def number_returned
  0
end

#可回复?false

消息默认不要求在向服务器发送消息后进行回复。

例子:

该消息是否需要回复?

message.replyable?

返回:

  • ( false )

    默认为不要求回复。

由于:

  • 2.0.0



95
96
97
# File 'lib/ Mongo/ 协议/message.rb', line 95

def 可回复?
  false
end

# Serialize (buffer = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil) ⇒ string也称为: to_s

将消息序列化为可通过网络发送的字节

参数:

  • 缓冲 string (默认为: BSON::ByteBuffer.new

    应插入消息的缓冲区

返回:

  • ( string )

    包含序列化消息的缓冲区



200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/ Mongo/ 协议/message.rb', line 200

def 序列化(缓冲 = BSON::ByteBuffer.new, max_bson_size = nil, bson_overhead = nil)
  max_size =
    if max_bson_size && bson_overhead
      max_bson_size + bson_overhead
    elsif max_bson_size
      max_bson_size
    end

  开始 = 缓冲.长度
  Serialize_header(缓冲)
  Serialize_fields(缓冲, max_size)
  缓冲.replace_int 32(开始, 缓冲.长度 - 开始)
end

#set_request_idFixnum

生成消息的请求ID

返回:

  • (Fixnum)

    用于向服务器发送消息的请求 ID。 服务器会将此 ID 放入回复的 response_to 字段中。



310
311
312
# File 'lib/ Mongo/ 协议/message.rb', line 310

def set_request_id
  @request_id = self.class.next_id
end