尝试使用二进制协议 returns 无效会话 ID 与 Elixir 连接到 OrientDB
Attempt to connect to OrientDB with Elixir using the binary protocol returns invalid Session-ID
我正在尝试使用 Elixir (1.0.5) 连接到 OrientDB (2.1 rc5)。两者都在我的本地计算机上 运行,我编写了以下代码作为第一次尝试连接:
{:ok, socket} = :gen_tcp.connect(to_char_list("localhost"), 2424, [{:packet, :raw}, :binary], 30_000)
a_r = receive do
{:tcp, ^socket, <<_succes, version>>} ->
msg = <<2 :: 8>> <> #REQEST_CONNECT
<<-1 :: 32>> <> #Negative Session-ID
<<byte_size("Test") :: 32>> <> "Test" <> #Driver-name
<<byte_size("0.0.1") :: 32>> <> "0.0.1" <> #Driver-version
<<version :: 16>> <> #Protocol-version
<<byte_size("") :: 32>> <> "" <> #Client-ID
<<byte_size("Binary") :: 32>> <> "Binary" <> #serialization-impl
<<1 :: 8>> <> #use token
<<byte_size("root") :: 32>> <> "root" <> #user-name
<<byte_size("orient") :: 32>> <> "orient" #usr-pwd
:gen_tcp.send(socket, msg)
receive do
msg -> msg
after
10000 -> :error1
end
after
10000 -> :error2
end
在运行这段代码之后,我得到第一个字节设置为0的结果,但Session-ID仍然是-1。始终返回一个令牌,无论我是否将其设置为 0 或 1。如果我发送一个正整数作为 Session-ID,连接将被拒绝,如果我发送无效密码也会发生这种情况。
我已经将我的代码与 orientjs driver, and checked whether all fields are present in the right order with the correct formatting in the manual 进行了比较,但我看不出哪里出错了。
您发送的数据中的字段顺序正确。令人心酸的是,当你做 <<_success, version>>
有点不走运时,你得到了正确的版本,因为 OrientDB 在连接时只将版本写为短(2 个字节),没有第一个字节区分 OK 或错误响应。由于版本很小(可能是 31),它被写成带有两个字节的 <<0, 31>>
,因此您的 version
变量具有正确的值。使用 <<version :: 16>>
代替 :).
但这不是问题,你问的是与 OrientDB 相关的问题,不涉及 Elixir。当客户端连接时,OrientDB 总是发送 -1
作为会话 ID,因此您看到的行为是预期的。此外,令牌总是被返回(无论你说你想要与否):如果你不想要它,则返回一个空令牌。如果您要求它,它可能仍然是空的(意味着服务器不支持基于令牌的身份验证)。
您必须在连接时发送 -1
的会话 ID(实际上是一个负整数),因为您仍然没有会话 ID,是的,传递正会话 ID 会导致 TCP如果会话 ID 不存在,连接将被丢弃。
所以,你没有做错 :) 你得到的响应将类似于:
<<0, 255, 255, 255, 255, 0, 0, 32, 102, 0, 0, 0, 0>>
这意味着:
0
- 确定响应
<<255, 255, 255, 255>>
(-1
作为 int32)- 由于新连接 ,会话 ID 为 -1
<<0, 0, 32, 102>>
(8294
作为 int32)- 新会话 的会话 ID,您必须将其用于相同的后续请求连接
<<0, 0, 0, 0>>
- 令牌(在本例中为空,因为 0
int32 是令牌字节的长度)
综上所述,用 Elixir 编写的 OrientDB 二进制驱动程序将在未来几天内开源(我知道,因为我写了它 :P),仅供参考。
我正在尝试使用 Elixir (1.0.5) 连接到 OrientDB (2.1 rc5)。两者都在我的本地计算机上 运行,我编写了以下代码作为第一次尝试连接:
{:ok, socket} = :gen_tcp.connect(to_char_list("localhost"), 2424, [{:packet, :raw}, :binary], 30_000)
a_r = receive do
{:tcp, ^socket, <<_succes, version>>} ->
msg = <<2 :: 8>> <> #REQEST_CONNECT
<<-1 :: 32>> <> #Negative Session-ID
<<byte_size("Test") :: 32>> <> "Test" <> #Driver-name
<<byte_size("0.0.1") :: 32>> <> "0.0.1" <> #Driver-version
<<version :: 16>> <> #Protocol-version
<<byte_size("") :: 32>> <> "" <> #Client-ID
<<byte_size("Binary") :: 32>> <> "Binary" <> #serialization-impl
<<1 :: 8>> <> #use token
<<byte_size("root") :: 32>> <> "root" <> #user-name
<<byte_size("orient") :: 32>> <> "orient" #usr-pwd
:gen_tcp.send(socket, msg)
receive do
msg -> msg
after
10000 -> :error1
end
after
10000 -> :error2
end
在运行这段代码之后,我得到第一个字节设置为0的结果,但Session-ID仍然是-1。始终返回一个令牌,无论我是否将其设置为 0 或 1。如果我发送一个正整数作为 Session-ID,连接将被拒绝,如果我发送无效密码也会发生这种情况。
我已经将我的代码与 orientjs driver, and checked whether all fields are present in the right order with the correct formatting in the manual 进行了比较,但我看不出哪里出错了。
您发送的数据中的字段顺序正确。令人心酸的是,当你做 <<_success, version>>
有点不走运时,你得到了正确的版本,因为 OrientDB 在连接时只将版本写为短(2 个字节),没有第一个字节区分 OK 或错误响应。由于版本很小(可能是 31),它被写成带有两个字节的 <<0, 31>>
,因此您的 version
变量具有正确的值。使用 <<version :: 16>>
代替 :).
但这不是问题,你问的是与 OrientDB 相关的问题,不涉及 Elixir。当客户端连接时,OrientDB 总是发送 -1
作为会话 ID,因此您看到的行为是预期的。此外,令牌总是被返回(无论你说你想要与否):如果你不想要它,则返回一个空令牌。如果您要求它,它可能仍然是空的(意味着服务器不支持基于令牌的身份验证)。
您必须在连接时发送 -1
的会话 ID(实际上是一个负整数),因为您仍然没有会话 ID,是的,传递正会话 ID 会导致 TCP如果会话 ID 不存在,连接将被丢弃。
所以,你没有做错 :) 你得到的响应将类似于:
<<0, 255, 255, 255, 255, 0, 0, 32, 102, 0, 0, 0, 0>>
这意味着:
0
- 确定响应<<255, 255, 255, 255>>
(-1
作为 int32)- 由于新连接 ,会话 ID 为 -1
<<0, 0, 32, 102>>
(8294
作为 int32)- 新会话 的会话 ID,您必须将其用于相同的后续请求连接<<0, 0, 0, 0>>
- 令牌(在本例中为空,因为0
int32 是令牌字节的长度)
综上所述,用 Elixir 编写的 OrientDB 二进制驱动程序将在未来几天内开源(我知道,因为我写了它 :P),仅供参考。