Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4971572
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2012-07-01 18:59:27

Problem:

In my project, I need to call erlang functions inside python to fulfil some concurrent computing tasks.

在我的项目中,我需要调用erlang方法在python实现一些并行计算任务。

Solution:

module implement the erlang nodes protocol and use python twisted network engine. Now, it is possible to call erlang nodes in python scripts.

Twotp模块实现了erlang节点协议和python Twisted 网络引擎的使用。现在,可以在python脚本中调用erlang节点。

I also found an example . Unfortunately, there are errors in the python sources codes when you make remote procedure call from twotp.NodeClientFactory. I followed the examples with the twotp source codes, and make the rpc from twotp.Process. This works.

在这里我还发现了一个例子。不幸的是从twotp.NodeClientFactory远程过程调用时,python源码中出现了错误。我遵循twotp源码,通过twotp.Process实现rpc协议。

Step 1: Setup erlang nodes.

第一步:安装erlang节点。


  1. %% Demo erlang program.
  2. %% Return hello message.

  3. -module(demo).
  4. -export([hello/1, ping/0, start/0]).

  5. %% Hello function, return hello message.
  6. hello(Name) ->
  7.     Message = "Hello, " ++ Name,
  8.     io:format(Message ++ "~n", []),
  9.     Message.

  10. %% ping loop, return the ping count.
  11. ping_loop(N) ->
  12.     receive
  13.         {get_id, From} ->
  14.             From ! {pong, N},
  15.             ping_loop(N+1)
  16.     end.

  17. %% ping function.
  18. ping() ->
  19.     pingsrv ! {get_id, self()},
  20.     receive
  21.         {pong, N} -> ok
  22.     end,
  23.     {pong, N}.

  24. %% start the server.
  25. start() ->
  26.     Pid = spawn_link(fun() -> ping_loop(1) end),
  27.     register(pingsrv, Pid).



 

Run the erlang program on “test” node.

运行erlang程序在“测试”节点。

  1. $ erl -sname test@localhost
  2. (test@localhost)1> demo:start().
  3. true

 

Step 2: Make rpc call in python.

第二步:在python调用rpc


 

  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3. #
  4. # BSD License
  5. # Copyright (c) 2011, Wang Qiang
  6. # All rights reserved.

  7. """
  8. Main python program.
  9. I will call erlang function here.
  10. """
  11. import sys
  12. import twotp
  13. from twisted.internet import reactor

  14. def error(e):
  15.     """
  16.     errback for twisted defered.
  17.     """
  18.     print 'Error:'
  19.     print e
  20.     reactor.stop()

  21. def do_pingpong(process, remote):
  22.     """
  23.     rpc for demo:ping.
  24.     """
  25.     def handle_pong(result):
  26.         """
  27.         callback for handling the demo:ping result.
  28.         """
  29.         text, id_ = result[0].text, result[1]
  30.         print "Got ping result: %s %d" % (text, id_)
  31.         reactor.callLater(1, do_pingpong, process, remote)
  32.     # Make rpc with two.Process.callRemote.
  33.     # call demo:ping() in remote node.
  34.     d = process.callRemote(remote, 'demo', 'ping')
  35.     d.addCallback(handle_pong)
  36.     d.addErrback(error)

  37. def call_hello(process, remote, name):
  38.     """
  39.     rpc for demo:hello.
  40.     """
  41.     def handle_hello(result):
  42.         """
  43.         callback for handling the demo:hello result.
  44.         """
  45.         print "Got hello results", result
  46.         text = ''.join(chr(c) for c in result).decode('latin1')
  47.         print 'String form:', text
  48.         do_pingpong(process, remote)
  49.     # Make rpc with two.Process.callRemote.
  50.     # call demo:hello() with name arg in remote node.
  51.     d = process.callRemote(remote, 'demo', 'hello', name)
  52.     d.addCallback(handle_hello)
  53.     d.addErrback(error)

  54. def main():
  55.     # get the erlang node name
  56.     remote = sys.argv[1]
  57.     # additional args.
  58.     name = sys.argv[2]
  59.     # get the erlang node cookie and setup the twotp.Process.
  60.     cookie = twotp.readCookie()
  61.     this_node = twotp.buildNodeName('demo_client')
  62.     process = twotp.Process(this_node, cookie)
  63.     # start twisted reactor.
  64.     reactor.callWhenRunning(call_hello, process, remote, name)
  65.     reactor.run()

  66. if __name__ == "__main__":
  67.     main()

Run python script and make it works.

运行python脚本并且使他工作。


 

  1. $ python main.py 'test' WangQiang
  2. Got hello results [72, 101, 108, 108, 111, 44, 32, 87, 97, 110, 103, 81, 105, 97, 110, 103]
  3. String form: Hello, WangQiang
  4. Got ping result: pong 2
  5. Got ping result: pong 3
  6. Got ping result: pong 4
  7. Got ping result: pong 5
  8. Got ping result: pong 6
  9. Got ping result: pong 7
  10. Got ping result: pong 8
  11. Got ping result: pong 9
  12. Got ping result: pong 10

from:

阅读(1935) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chanqping2014-05-14 16:01:34

为什么我在一台机上运行你给的程序,erlang端会出Invalid distribution message: {6,'',<5958.3.0>,rex}
这样的错误呢