2017-09-19 10 views
1

私はElixirとPythonの間で通信したいと思います。私はNIFやものを使いたくありません - 後でPython以外の言語を使うことができるので、zeroMQを使って疎結合したほうが好きです。私は、Erlangのzeromqのネイティブ実装であるchumakライブラリを使用しており、よく維持されているようです。私はパブのサブのために過去にそれを正常に使用しました。ZeroMQディーラーソケットはElixirの下で動作しません(Erlangのchumakを使用)

私は、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、while: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の両方のアーキテクチャでこれを試しましたが、問題は同じです。

すべてのエリクシールコードは、ディーラルータ用のchumak exampleのErlangバージョンに基づいています。

マイmix.exsのDEPSは次のようになります。私は見

[ 
     {:chumak, "~> 1.2"}, 
     {:msgpack, "~> 0.7.0"} 

] 

答えて

2

だけ明らかなことは、send_multipartの使用です。ソースでその署名:あなたはこれをやっている

-spec send_multipart(SocketPid::pid(), [Data::binary()]) -> ok. 

は:

:chumak.send_multipart(sock2, ['a', 'b', 'hello from dealer socket']) 

------------ 
iex(2)> is_binary('a') 
false 
iex(3)> is_binary('hello from dealer socket') 
false 

そうでなければ、私はあなたのコードとchumakのレポにあるサンプルコードの違いの多くを見ることができません。

+1

ニース。私はちょうどそれを使用してテストしました:chumak.send_multipart(sock2、[<<1, 2>>、<<3, 4>>]とそれは正常に動作しますので、基本的に私は型エラーがありました。私は単一引用符で_erlangバイナリ_たとえば、["123"、 "456"]を含むエリクシールのバイナリが使用されます。 –

関連する問題