-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.rb
86 lines (71 loc) · 1.82 KB
/
client.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
require 'rubygems'
require 'ffi-rzmq'
class ZnowflakeMessage
class Layout < FFI::Struct
layout :b0, :uint8,
:b1, :uint8,
:b2, :uint8,
:b3, :uint8,
:b4, :uint8,
:b5, :uint8,
:b6, :uint8,
:b7, :uint8
end
def initialize msg_struct = nil
if msg_struct
@msg_t = msg_struct
@data = Layout.new @msg_t.data
else
@pointer = FFI::MemoryPointer.new :byte, Layout.size, true
@data = Layout.new @pointer
end
end
def size
@size = @msg_t.size
end
def id
# Convert from network byte order
(@data[:b0] << 56) | (@data[:b1] << 48) | (@data[:b2] << 40) | (@data[:b3] << 32) |
(@data[:b4] << 24) | (@data[:b5] << 16) | (@data[:b6] << 8) | @data[:b7]
end
end
# Pull apart and print the ID
@bit_len = {
:time => 39,
:machine => 15,
:seq => 10
}
@bit_shift = {
:time => @bit_len[:seq] + @bit_len[:machine],
:machine => @bit_len[:seq]
}
@bit_mask = {
:machine => (1 << @bit_len[:machine]) - 1,
:seq => (1 << @bit_len[:seq]) - 1
}
@epoch = 1337000000
def print_id id
ts = (@epoch * 1000) + (id >> @bit_shift[:time])
sec = ts / 1000
msec = ts - (sec * 1000)
machine = (id >> @bit_shift[:machine]) & @bit_mask[:machine]
seq = id & @bit_mask[:seq]
puts "id: #{id}"
puts "machine: #{machine}"
puts "datetime: #{Time.at sec}"
puts "timestamp: #{sec}"
puts "(msec, seq): (#{msec}, #{seq})"
puts
end
# Grab some IDs off the socket
@port = 23138
context = ZMQ::Context.new
socket = context.socket ZMQ::REQ
socket.connect "tcp://127.0.0.1:#{@port}"
100.times do
socket.send_string ''
message = ZMQ::Message.new
successful_read = socket.recvmsg message
message = ZnowflakeMessage.new message if successful_read
print_id message.id
end