Erlang库的Elixir元帅ISO 8583消息错误

时间:2018-09-18 10:49:11

标签: erlang elixir phoenix-framework iso8583

我是elixir的新手,我需要使用此语言和Phoenix框架创建ISO 8583客户端。我从stackoverflow线程here中找到了一个Erlang库,编译成功并遵循了存储库here中的示例,但是在整理消息时出错。这是我的Elixir代码,用于整理邮件:

msg1 = :erl8583_message.new()
msg2 = :erl8583_message.set_mti("0800", msg1)
msg3 = :erl8583_message.set(3, "300000", msg2)
msg4 = :erl8583_message.set(24, "045", msg3)
msg5 = :erl8583_message.set(41, "11111111", msg4)
msg6 = :erl8583_message.set(42, "222222222222222", msg5)
msg7 = :erl8583_message.set(63, "This is a Test Message", msg6)
marshalled = :erl8583_marshaller_ascii.marshal(msg7)

这只是回购示例中的一种灵丹妙药。这是我在运行应用程序时遇到的错误:

[error] #PID<0.438.0> running TestlangIsoClientWeb.Endpoint (cowboy_protocol) terminated
Server: 127.0.0.1:4001 (http)
Request: POST /api/process
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in :erl8583_marshaller_ascii.marshal_data_element/2
        (erl8583) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/erl8583/src/erl8583_marshaller_ascii.erl:168: :erl8583_marshaller_ascii.marshal_data_element({:n, :fixed, 4}, "0800")
        (erl8583) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/erl8583/src/erl8583_marshaller.erl:108: :erl8583_marshaller.marshal/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:61: TestlangIsoClientWeb.MyController.process/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:1: TestlangIsoClientWeb.MyController.action/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:1: TestlangIsoClientWeb.MyController.phoenix_controller_pipeline/2
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.plug_builder_call/2
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

有什么我想让它起作用的东西吗?任何帮助将不胜感激。

已更新

我试图将字符串参数更改为charlist,但仍然遇到相同的错误。这是代码段:

def test(conn, _params) do
  IO.puts("Test")
  msg1 = :erl8583_message.new()
  msg2 = :erl8583_message.set_mti('0800', msg1)
  msg3 = :erl8583_message.set(3, '300000', msg2)
  msg4 = :erl8583_message.set(24, '045', msg3)
  msg5 = :erl8583_message.set(41, '11111111', msg4)
  msg6 = :erl8583_message.set(42, '222222222222222', msg5)
  msg7 = :erl8583_message.set(63, 'This is a Test Message', msg6)
  marshalled = :erl8583_marshaller_ascii.marshal(msg7)
  json(conn, %{status: "ok"})
end

这是堆栈跟踪中提到的函数erl8583_marshaller.erl:108

marshal(Message, MarshalHandlers) ->
    OptionsRecord = parse_options(MarshalHandlers, #marshal_options{}),
    {Marshalled1, Message1} = init_marshalling(OptionsRecord, Message),
    MarshalledMti = encode_mti(OptionsRecord, Message1),  % --- Line 108
    Marshalled2 = <<Marshalled1/binary, MarshalledMti/binary>>,
    {MarshalledBitmap, Message2} = encode_bitmap(OptionsRecord, Message1),
    Marshalled3 = <<Marshalled2/binary, MarshalledBitmap/binary>>,
    MarshalledFields = encode_fields(OptionsRecord, Message2),
    Marshalled4 = <<Marshalled3/binary, MarshalledFields/binary>>,
    end_marshalling(OptionsRecord, Message2, Marshalled4).

这是stacktrace中提到的函数erl8583_marshaller_ascii.erl:168

%%
%% Local Functions
%%
marshal_data_element({n, llvar, Length}, FieldValue) when length(FieldValue) =< Length ->
    erl8583_convert:integer_to_string(length(FieldValue), 2) ++ FieldValue;

我不明白为什么对该函数的调用未能与我的函数发送的参数{:n, :fixed, 4}, "0800"匹配。我试图将双引号更改为单引号没有成功。还有其他建议吗?

2 个答案:

答案 0 :(得分:3)

代码中可能存在错误。 您可以参考此问题here

有一个相对较新的灵丹妙药库。

它称为ale8583

有关此文件的文档仍在发布,但看起来很有希望。

您可以签出。

答案 1 :(得分:0)

尝试传递字符列表而不是字符串:

msg1 = :erl8583_message.new()
msg2 = :erl8583_message.set_mti('0800', msg1)
msg3 = :erl8583_message.set(3, '300000', msg2)
msg4 = :erl8583_message.set(24, '045', msg3)
msg5 = :erl8583_message.set(41, '11111111', msg4)
msg6 = :erl8583_message.set(42, '222222222222222', msg5)
msg7 = :erl8583_message.set(63, 'This is a Test Message', msg6)
marshalled = :erl8583_marshaller_ascii.marshal(msg7)

这里可能会造成混乱:

  • Erlang称为“字符串”并用双引号("foo")表示,Elixir称为“ charlists”并用单引号('foo')表示。
  • Elixir所说的“字符串”并用双引号("foo")表示,Erlang所说的“ binaries”用双引号加尖括号(<<"foo">>)表示。

似乎erl8583库希望整个使用Erlang字符串。