首页 > 解决方案 > 使用 Erlang 库的 Elixir 编组 ISO 8583 消息错误

问题描述

我是 elixir 的新手,我需要使用这种语言和 Phoenix 框架创建 ISO 8583 客户端。我在这里从 stackoverflow 线程中找到了一个 Erlang 库,编译成功并按照这里存储库中的示例进行操作,但在编组消息时出错。这是我编组消息的 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)

这只是来自 repo 示例的灵丹妙药版本。这是我在运行应用程序时遇到的错误:

[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).

这是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"从我的函数发送的参数不匹配。我试图将双引号更改为单引号,但没有成功。还有其他建议我该怎么做吗?

标签: erlangelixirphoenix-frameworkiso8583

解决方案


代码中可能存在错误。你可以在这里参考这个问题

有一个相对较新的长生不老药库。

它叫做ale8583

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

你可以检查一下。


推荐阅读