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

直接已知子类

Compressed 、 GetMore 、 KillCursors 、 Msg 、 Query 、 Reply

常量摘要折叠

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_PACK、Serializers::INT32_PACK、Serializers::INT64_PACK、Serializers::NULL、Serializers::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 类的实例

引发:



231
232
233
234
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
# File 'lib/ Mongo/ 协议/message.rb', line 231

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.字段.每 do |字段|
    if 字段[:multi]
      message.deserialize_array(buf, 字段, 选项)
    else
      message.deserialize_field(buf, 字段, 选项)
    end
  end
  message.fix_after_deserialization if message.is_a?(消息)
  message.也许_inflate
end

。deserialize_header(io) ⇒ 数组<Fixnum>

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

反序列化消息头

参数:

  • io ( IO ) —

    包含标头的流。

返回:

  • ( Array<Fixnum> ) —

    反序列化的标头。



332
333
334
# File 'lib/ Mongo/ 协议/message.rb', line 332

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

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

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

一种声明消息字段的方法

参数:

  • 名称 ( string ) —

    字段名称

  • 类型 (模块) —

    特定于类型的序列化策略

  • 多 ( true、false、Symbol ) (默认为: 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)


352
353
354
355
356
357
358
359
360
# File 'lib/ Mongo/ 协议/message.rb', line 352

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

  attr_reader 名称
end

。字段 ⇒ 整数

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

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

返回:

  • ( Integer ) —

    消息类的字段



323
324
325
# File 'lib/ Mongo/ 协议/message.rb', line 323

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

实例方法详细信息

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

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

参数:

返回:

  • ( true , false ) —

    消息的相等性。



283
284
285
286
287
288
289
290
291
# File 'lib/ Mongo/ 协议/message.rb', line 283

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

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

#deserialize_数组(io, 字段, options = {}) ⇒ 数组

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

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

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

参数:

  • io ( IO ) —

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

  • 字段 (哈希) —

    表示字段的哈希。

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

选项哈希 ( options ):

  • :deserialize_as_bson (布尔值) —

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

返回:

  • ( Array ) —

    反序列化数组。



377
378
379
380
381
382
# File 'lib/ Mongo/ 协议/message.rb', line 377

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

#deserialize_field(io, 字段, options = {}) ⇒ 对象

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

反序列化单个字段到此消息。

参数:

  • io ( IO ) —

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

  • 字段 (哈希) —

    表示字段的哈希。

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

选项哈希 ( options ):

  • :deserialize_as_bson (布尔值) —

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

返回:

  • ( Object ) —

    反序列化字段值。



395
396
397
398
399
400
# File 'lib/ Mongo/ 协议/message.rb', line 395

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

#字段 ⇒ 数组<Hash>

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

获取消息类字段的方法

返回:

  • ( Array<Hash> ) —

    消息类的字段



406
407
408
# File 'lib/ Mongo/ 协议/message.rb', line 406

def 字段
  self.class.字段
end

# hash =" Fixnum "

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

返回:

  • (Fixnum) —

    消息的哈希代码。



297
298
299
# File 'lib/ Mongo/ 协议/message.rb', line 297

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

#也许_add_server_api (server_api) ⇒对象

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

参数:

  • server_api (哈希) —

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

引发:

  • ( NotImplementedError )


171
172
173
# File 'lib/ Mongo/ 协议/message.rb', line 171

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
# File 'lib/ Mongo/ 协议/message.rb', line 150

def Maybe_decrypt(_context)
  self
end

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

可以使用 libmongocrypt 加密此消息。

参数:

返回:

  • (Mongo::Protocol::Msg) —

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



162
163
164
165
# File 'lib/ Mongo/ 协议/message.rb', line 162

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

#也许_inflate ⇒ Protocol::Message

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

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

返回:

  • (Protocol::Message) —

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

由于:

  • 2.5.0



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

def 也许_inflate
  self
end

# number_returned ⇒ 0

协议消息的默认返回值。

返回:

  • ( 0 ) —

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

由于:

  • 2.5.0



315
316
317
# File 'lib/ Mongo/ 协议/message.rb', line 315

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 ) —

    包含序列化消息的缓冲区



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/ Mongo/ 协议/message.rb', line 196

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

#serialize_fields(buffer, max_bson_size = nil) ⇒ String

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

将消息字段序列化为缓冲区

参数:

  • 缓冲 ( string ) —

    用于接收字段的缓冲区

返回:

  • ( string ) —

    具有序列化字段的缓冲区



415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/ Mongo/ 协议/message.rb', line 415

def Serialize_fields(缓冲, max_bson_size = nil)
  字段.每 do |字段|
    值 = instance_variable_get(字段[:name])
    if 字段[:multi]
      值.每 do |列项|
        if 字段[:type].respond_to?(:size_limited?)
          字段[:type].序列化(缓冲, 列项, max_bson_size)
        else
          字段[:type].序列化(缓冲, 列项)
        end
      end
    elsif 字段[:type].respond_to?(:size_limited?)
      字段[:type].序列化(缓冲, 值, max_bson_size)
    else
      字段[:type].序列化(缓冲, 值)
    end
  end
end

#set_request_id ⇒ Fixnum

生成消息的请求ID

返回:

  • (Fixnum) —

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



306
307
308
# File 'lib/ Mongo/ 协议/message.rb', line 306

def set_request_id
  @request_id = self.class.next_id
end