我想在Elixir和Python之間進行通信。我不想使用NIF和其他東西 - 我寧願使用zeroMQ進行鬆散耦合,因爲這將允許我以後使用Python以外的其他語言。我正在使用chumak庫,它是Erlang的zeromq的本地實現,並且看起來很好。過去,我已經成功地將它用於pub sub。ZeroMQ經銷商套接字不能在Elixir下工作(使用Erlang的chumak)
除了pub-sub,我發現req-rep和req-router套接字工作正常。然而經銷商路由器沒有。這非常重要,因爲只有經銷商和路由器才能在zeromq中爲您提供真正的異步。
下面是路由器端的Python代碼:
import zmq
context = zmq.Context()
rout = context.socket(zmq.ROUTER)
rout.bind("tcp://192.168.1.192:8760")
這裏是藥劑REQ代碼的正常工作......
iex(1)> {ok, sock1} = :chumak.socket(:req, 'reqid')
{:ok, #PID<0.162.0>}
iex(2)> {ok, _peer} = :chumak.connect(sock1, :tcp, '192.168.1.192', 8760)
{:ok, #PID<0.164.0>}
iex(3)> :chumak.send(sock1, 'hello from req socket')
:ok
....因爲我得到它的Python端:
In [5]: xx = rout.recv_multipart()
In [6]: xx
Out[6]: ['reqid', '', 'hello from req socket']
然而,這裏是我所得到的,如果我嘗試在藥劑側經銷商插座:
iex(4)> {ok, sock2} = :chumak.socket(:dealer, 'dealid')
{:ok, #PID<0.170.0>}
iex(5)> {ok, _peer} = :chumak.connect(sock2, :tcp, '192.168.1.192', 8760)
{:ok, #PID<0.172.0>}
iex(6)> :chumak.send(sock2, 'hello from dealer socket')
{:error, :not_implemented_yet}
iex(7)> :chumak.send_multipart(sock2, ['a', 'b', 'hello from dealer socket'])
22:13:38.705 [error] GenServer #PID<0.172.0> terminating
** (FunctionClauseError) no function clause matching in :chumak_protocol.encode_more_message/3
(chumak) /home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_protocol.erl:676: :chumak_protocol.encode_more_message('a', :null, %{})
(stdlib) lists.erl:1354: :lists.mapfoldl/3
(chumak) /home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_protocol.erl:664: :chumak_protocol.encode_message_multipart/3
(chumak) /home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_peer.erl:159: :chumak_peer.handle_cast/2
(stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:686: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:send, ['a', 'b', 'hello from dealer socket'], {#PID<0.160.0>, #Reference<0.79795089.2401763329.172383>}}}
State: {:state, :ready, '192.168.1.192', 8760, :client, [], :dealer, 'dealid', [], {3, 0}, #Port<0.4968>, {:decoder, :ready, 0, nil, nil, {:some, 3}, {:some, 0}, %{}, :null, false}, #PID<0.170.0>, {[], []}, [], false, false, false, :null, %{}}
22:13:38.710 [info] [:unhandled_handle_info, {:module, :chumak_socket}, {:msg, {:EXIT, #PID<0.172.0>, {:function_clause, [{:chumak_protocol, :encode_more_message, ['a', :null, %{}], [file: '/home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_protocol.erl', line: 676]}, {:lists, :mapfoldl, 3, [file: 'lists.erl', line: 1354]}, {:chumak_protocol, :encode_message_multipart, 3, [file: '/home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_protocol.erl', line: 664]}, {:chumak_peer, :handle_cast, 2, [file: '/home/tbrowne/code/elixir/chutest/deps/chumak/src/chumak_peer.erl', line: 159]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 616]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 686]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}}]
正如你可以看到我得到這個巨大的錯誤的:chumak.send_multipart,而:chumak.send甚至不工作。這裏發生了什麼?
經銷商插座工作正常的方式從Python方:
import zmq
context = zmq.Context()
deal = context.socket(zmq.DEALER)
deal.setsockopt_string(zmq.IDENTITY, u"Thomas")
deal.connect("tcp://192.168.1.192:8760")
deal.send("hello from python deal")
現在在路由器端:
In [5]: xx = rout.recv_multipart()
In [6]: xx
Out[6]: ['reqid', '', 'hello from req socket']
In [7]: dd = rout.recv_multipart()
In [8]: dd
Out[8]: ['Thomas', 'hello from python deal']
所以我不知道如果我有一個語法,或錯誤類型,在我的Elixir chumak經銷商插座中,或者它只是一個錯誤。我在amd64和armv7l架構上都試過這個,問題是一樣的。
所有elixir代碼都基於經銷商路由器的chumak example的Erlang版本。
我mix.exs DEPS看起來是這樣的:
[
{:chumak, "~> 1.2"},
{:msgpack, "~> 0.7.0"}
]
不錯。我剛剛測試過使用:chumak.send_multipart(sock2,[<<1, 2>>,<<3, 4>>],並且工作正常。所以基本上我有一個類型錯誤。我想我需要使用_erlang二進制文件_通過單引號機制,但實際上將採取包括例如[「123」,「456」]的Elixir二進制文件。真棒。 –