`
san_yun
  • 浏览: 2663558 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

hessian的python客户端

 
阅读更多

今天简单看了一下hessian的客户端,全部代码就480行,非常简单啊,完全可以模仿此代码写各种http客户端。

最核心的代码:

    request = HessianWriter().write_call(method, params)

    import httplib

    h = httplib.HTTP(self._host)
    h.putrequest("POST", self._uri)

    # required by HTTP/1.1
    h.putheader("Host", self._host)

    h.putheader("User-Agent", "hessianlib.py/%s" % __version__)
    h.putheader("Content-Length", str(len(request)))

    h.endheaders()

    h.send(request)

    errcode, errmsg, headers = h.getreply()

    if errcode != 200:
        raise ProtocolError(self._url, errcode, errmsg, headers)

    return self.parse_response(h.getfile())

 

全部:

#
# A Hessian client interface for Python.  The date and long types require
# Python 2.2 or later.
#
# The Hessian proxy is used as follows:
#
# proxy = Hessian("http://hessian.caucho.com/test/basic")
#
# print proxy.hello()
#
# --------------------------------------------------------------------
#
# The Apache Software License, Version 1.1
#
# Copyright (c) 2001-2002 Caucho Technology, Inc.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# 3. The end-user documentation included with the redistribution, if
#    any, must include the following acknowlegement:
#       "This product includes software developed by the
#        Caucho Technology (http://www.caucho.com/)."
#    Alternately, this acknowlegement may appear in the software itself,
#    if and wherever such third-party acknowlegements normally appear.
#
# 4. The names "Hessian", "Resin", and "Caucho" must not be used to
#    endorse or promote products derived from this software without prior
#    written permission. For written permission, please contact
#    info@caucho.com.
#
# 5. Products derived from this software may not be called "Resin"
#    nor may "Resin" appear in their names without prior written
#    permission of Caucho Technology.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# --------------------------------------------------------------------
#
# Credits: hessianlib.py was inspired and partially based on
# xmlrpclib.py created by Fredrik Lundh at www.pythonware.org
#
import string, time
import urllib
from types import *
from struct import unpack
from struct import pack

__version__ = "0.1"


# --------------------------------------------------------------------
# Exceptions

class Error:
    # base class for client errors
    pass

class ProtocolError(Error):
    # Represents an HTTP protocol error
    def __init__(self, url, code, message, headers):
    self.url = url
    self.code = code
    self.message = message
    self.headers = headers

    def __repr__(self):
    return (
        "<ProtocolError for %s: %s %s>" %
        (self.url, self.code, self.message)
        )

class Fault(Error):
    # Represents a fault from Hessian
    def __init__(self, code, message, **detail):
    self.code = code
    self.message = message

    def __repr__(self):
    return "<HessianFault %s: %s>" % (self.code, self.message)

# --------------------------------------------------------------------
# Wrappers for Hessian data types non-standard in Python
#

#
# Boolean -- use the True or False constants
#
class Boolean:
    def __init__(self, value = 0):
    self.value = (value != 0)

    def _hessian_write(self, out):
    if self.value:
        out.write('T')
    else:
        out.write('F')

    def __repr__(self):
    if self.value:
        return "<True at %x>" % id(self)
    else:
        return "<False at %x>" % id(self)

    def __int__(self):
    return self.value

    def __nonzero__(self):
    return self.value

True, False = Boolean(1), Boolean(0)

#
# Date - wraps a time value in seconds
#
class Date:
    def __init__(self, value = 0):
    self.value = value

    def __repr__(self):
    return ("<Date %s at %x>" %
                (time.asctime(time.localtime(self.value)), id(self)))

    def _hessian_write(self, out):
    out.write("d")
    out.write(pack(">q", self.value * 1000.0))
#
# Binary - binary data
#

class Binary:
    def __init__(self, data=None):
    self.data = data

    def _hessian_write(self, out):
    out.write('B')
    out.write(pack('>H', len(self.data)))
    out.write(self.data)

# --------------------------------------------------------------------
# Marshalling and unmarshalling code

#
# HessianWriter - writes Hessian data from Python objects
#
class HessianWriter:
    dispatch = {}

    def write_call(self, method, params):
    self.refs = {}
    self.ref = 0
    self.__out = []
    self.write = write = self.__out.append

        write("c\x01\x00m");
        write(pack(">H", len(method)));
        write(method);
    for v in params:
        self.write_object(v)
        write("z");
    result = string.join(self.__out, "")
    del self.__out, self.write, self.refs
    return result

    def write_object(self, value):
    try:
        f = self.dispatch[type(value)]
    except KeyError:
        raise TypeError, "cannot write %s objects" % type(value)
    else:
        f(self, value)

    def write_int(self, value):
    self.write('I')
    self.write(pack(">l", value))
    dispatch[IntType] = write_int

    def write_long(self, value):
    self.write('L')
    self.write(pack(">q", value))
    dispatch[LongType] = write_long

    def write_double(self, value):
    self.write('D')
    self.write(pack(">d", value))
    dispatch[FloatType] = write_double

    def write_string(self, value):
    self.write('S')
    self.write(pack('>H', len(value)))
    self.write(value)
    dispatch[StringType] = write_string

    def write_reference(self, value):
        # check for and write circular references
        # returns 1 if the object should be written, i.e. not a reference
    i = id(value)
    if self.refs.has_key(i):
        self.write('R')
        self.write(pack(">L", self.refs[i]))
        return 0
    else:
        self.refs[i] = self.ref
        self.ref = self.ref + 1
        return 1

    def write_list(self, value):
    if self.write_reference(value):
        self.write("Vt\x00\x00I");
        self.write(pack('>l', len(value)))
        for v in value:
            self.__write(v)
        self.write('z')
    dispatch[TupleType] = write_list
    dispatch[ListType] = write_list

    def write_map(self, value):
    if self.write_reference(value):
        self.write("Mt\x00\x00")
        for k, v in value.items():
            self.__write(k)
            self.__write(v)
        self.write("z")
    dispatch[DictType] = write_map

    def write_instance(self, value):
    # check for special wrappers
    if hasattr(value, "_hessian_write"):
        value._hessian_write(self)
    else:
        fields = value.__dict__
        if self.write_reference(fields):
            self.write("Mt\x00\x00")
            for k, v in fields.items():
                self.__write(k)
                self.__write(v)
            self.write("z")
    dispatch[InstanceType] = write_instance

#
# Parses the results from the server
#
class HessianParser:
    def __init__(self, f):
    self._f = f
        self._peek = -1
    # self.read = f.read
    self._refs = []

    def read(self, len):
    if self._peek >= 0:
      value = self._peek
      self._peek = -1
      return value
    else:
      return self._f.read(len)

    def parse_reply(self):
        # parse header 'c' x01 x00 'v' ... 'z'
    read = self.read
    if read(1) != 'r':
        self.error()
    major = read(1)
    minor = read(1)

        value = self.parse_object()

    if read(1) == 'z':
        return value
    self.error() # actually a fault

    def parse_object(self):
    # parse an arbitrary object based on the type in the data
    return self.parse_object_code(self.read(1))

    def parse_object_code(self, code):
    # parse an object when the code is known
    read = self.read

    if code == 'N':
        return None

    elif code == 'T':
        return True

    elif code == 'F':
        return False

    elif code == 'I':
        return unpack('>l', read(4))[0]

    elif code == 'L':
        return unpack('>q', read(8))[0]

    elif code == 'D':
        return unpack('>d', read(8))[0]

    elif code == 'd':
        ms = unpack('>q', read(8))[0]

        return Date(int(ms / 1000.0))

    elif code == 'S' or code == 'X':
        return self.parse_string()

    elif code == 'B':
        return Binary(self.parse_string())

    elif code == 'V':
        self.parse_type() # skip type
        self.parse_length()           # skip length
        list = []
        self._refs.append(list)
        ch = read(1)
        while ch != 'z':
        list.append(self.parse_object_code(ch))
        ch = read(1)
        return list

    elif code == 'M':
        self.parse_type() # skip type
        map = {}
        self._refs.append(map)
        ch = read(1)
        while ch != 'z':
        key = self.parse_object_code(ch)
        value = self.parse_object()
        map[key] = value
        ch = read(1)
        return map

    elif code == 'R':
        return self._refs[unpack('>l', read(4))[0]]

    elif code == 'r':
        self.parse_type()       # skip type
        url = self.parse_type() # reads the url
        return Hessian(url)

    else:
        raise "UnknownObjectCode %d" % code

    def parse_string(self):
    f = self._f
    len = unpack('>H', f.read(2))[0]
    return f.read(len)

    def parse_type(self):
    f = self._f
    code = self.read(1)
    if code != 't':
      self._peek = code
      return ""
    len = unpack('>H', f.read(2))[0]
    return f.read(len)

    def parse_length(self):
    f = self._f
    code = self.read(1);
    if code != 'l':
      self._peek = code
      return -1;
    len = unpack('>l', f.read(4))
    return len

    def error(self):
    raise "FOO"

#
# Encapsulates the method to be called
#
class _Method:
    def __init__(self, invoker, method):
    self._invoker = invoker
    self._method = method

    def __call__(self, *args):
    return self._invoker(self._method, args)

# --------------------------------------------------------------------
# Hessian is the main class.  A Hessian proxy is created with the URL
# and then called just as for a local method
#
# proxy = Hessian("http://www.caucho.com/hessian/test/basic")
# print proxy.hello()
#
class Hessian:
    """Represents a remote object reachable by Hessian"""

    def __init__(self, url):
    # Creates a Hessian proxy object

    self._url = url

    # get the uri
    type, uri = urllib.splittype(url)
    if type != "http":
        raise IOError, "unsupported Hessian protocol"

    self._host, self._uri = urllib.splithost(uri)

    def __invoke(self, method, params):
    # call a method on the remote server

    request = HessianWriter().write_call(method, params)

    import httplib

    h = httplib.HTTP(self._host)
    h.putrequest("POST", self._uri)

    # required by HTTP/1.1
    h.putheader("Host", self._host)

    h.putheader("User-Agent", "hessianlib.py/%s" % __version__)
    h.putheader("Content-Length", str(len(request)))

    h.endheaders()

    h.send(request)

    errcode, errmsg, headers = h.getreply()

    if errcode != 200:
        raise ProtocolError(self._url, errcode, errmsg, headers)

    return self.parse_response(h.getfile())

    def parse_response(self, f):
    # read response from input file, and parse it

    parser = HessianParser(f)
    value = parser.parse_reply()
    f.close()

    return value

    def _hessian_write(self, out):
    # marshals the proxy itself
    out.write("rt\x00\x00S")
    out.write(pack(">H", len(self._url)))
    out.write(self._url)

    def __repr__(self):
    return "<HessianProxy %s>" % self._url

    __str__ = __repr__

    def __getattr__(self, name):
    # encapsulate the method call
    return _Method(self.__invoke, name)

#
# Testing code.
#
if __name__ == "__main__":

    proxy = Hessian("http://hessian.caucho.com/test/test")

    try:
    print proxy.hello()
    except Error, v:
    print "ERROR", v
 

 

分享到:
评论
2 楼 san_yun 2013-11-14  
某某某 写道
python hessianlib.py

执行__main__方法报错,是怎么回事?

Traceback (most recent call last):
  File "hessianlib.py", line 479, in ?
    print proxy.hello()
  File "hessianlib.py", line 396, in __call__
    return self._invoker(self._method, args)
  File "hessianlib.py", line 445, in __invoke
    return self.parse_response(h.getfile())
  File "hessianlib.py", line 451, in parse_response
    value = parser.parse_reply()
  File "hessianlib.py", line 284, in parse_reply
    value = self.parse_object()
  File "hessianlib.py", line 292, in parse_object
    return self.parse_object_code(self.read(1))
  File "hessianlib.py", line 359, in parse_object_code
    raise "UnknownObjectCode %d" % code
TypeError: int argument required

是Hessian的版本过低吗?


hessian的python版本就是坑,没有实现完整,我后来都没有用了,建议你直接通过json传递数据吧。
1 楼 某某某 2013-11-14  
python hessianlib.py

执行__main__方法报错,是怎么回事?

Traceback (most recent call last):
  File "hessianlib.py", line 479, in ?
    print proxy.hello()
  File "hessianlib.py", line 396, in __call__
    return self._invoker(self._method, args)
  File "hessianlib.py", line 445, in __invoke
    return self.parse_response(h.getfile())
  File "hessianlib.py", line 451, in parse_response
    value = parser.parse_reply()
  File "hessianlib.py", line 284, in parse_reply
    value = self.parse_object()
  File "hessianlib.py", line 292, in parse_object
    return self.parse_object_code(self.read(1))
  File "hessianlib.py", line 359, in parse_object_code
    raise "UnknownObjectCode %d" % code
TypeError: int argument required

是Hessian的版本过低吗?

相关推荐

    hessian案例,hessian案例

    通过Hessian,Java服务可以被Python客户端调用,反之亦然。 5. **性能比较**:压缩包内的"java 几种远程服务调用协议的比较.txt"可能包含关于Hessian与其他RPC协议(如RMI、SOAP、gRPC等)的性能对比。通常,...

    PyDubbo:用于dubbo rpc框架的python客户端

    PyDubbo这是一个python实现的dubbo服务调用的客户端协议支持由于dubbo支持多种协议扩展,目前只开发了dubbo服务的默认协议:dubbo+hessian2的支持其它协议的支持慢慢来吧安装运行环境由于dubbo协议的限制,所以进行...

    hessian

    4. **跨语言支持**:虽然最初是为Java设计的,但Hessian也有其他语言的实现,比如Python、C++、C#等,因此可以在多种语言之间进行通信。 在【描述】中提到的博客链接,可能详细介绍了如何使用Hessian进行客户端和...

    Hessian 接口 Java Python.docx

    Java的Hessian库通常集成在如Resin这样的应用服务器中,例如提供的链接所示的Resin 3.1和4.0版本的文档和API参考,可以帮助开发者深入理解如何在Java和Python之间建立和使用Hessian接口。通过这些接口,开发者可以...

    Hessian应用

    - **跨语言支持**:除了Java之外,Hessian还支持.NET、Python等多种编程语言,这使得开发者可以在异构系统之间轻松地实现服务交互。 #### 使用场景 Hessian适用于需要高性能远程服务调用的应用场景,尤其适合于...

    Hessian Binary Web Service Protocol远程接口调用入门Demo

    此外,Hessian支持Java、C++、Python等多种编程语言,具有良好的跨平台性。对于需要频繁交互且数据量不大的Web服务,Hessian是一个理想的选择。 接下来,我们来看看Hessian的调用流程: 1. **服务端实现**:在...

    Hessian多个版本打包下载

    此外,Hessian4.0.7可能支持更多的编程语言,如Python、Ruby等,扩大了Hessian的适用范围。同时,该版本可能对多线程和并发处理进行了优化,以适应高并发场景下的服务通信需求。 下载这些不同版本的Hessian,开发者...

    Hessian(Spring集成的)的应用与研究

    Hessian支持Java、C++、Python等多种语言,便于跨平台的远程调用。 二、Spring集成Hessian Spring通过其AOP(面向切面编程)和IoC(控制反转)理念,为Hessian提供了便捷的整合方式。在Spring中,我们可以定义一个...

    springMVC hessian

    Hessian 支持 Java、C++、Python 等多种语言,使得跨语言的服务调用成为可能。Hessian 的优点在于它能够自动序列化和反序列化对象,减少了网络传输的数据量,提高了服务调用的效率。在分布式系统中,Hessian 可以...

    Java Hessian小试(转)

    4. **简单易用**:Hessian提供了客户端和服务端的API,使得开发者可以快速实现RPC服务。 在Java中,使用Hessian主要涉及以下几个步骤: **1. 引入依赖** 在项目中引入Hessian的库,通常是Caucho公司的Hessian库,...

    hessian php与java通讯demo源码

    Hessian支持多种语言,包括Java、PHP、Python等,这使得跨平台的集成变得容易。 在提供的压缩包中,我们有三个文件:`java_client.rar`、`java_server.rar`和`php-client.rar`。这些文件分别代表了Java客户端、Java...

    hessian示例远程轻量级传输

    3. **跨语言支持**:虽然起源于Java,但Hessian也提供了对其他语言如C++、Python等的支持,便于构建多语言环境下的分布式系统。 4. **透明性**:Hessian允许远程调用像本地方法调用一样,提高了开发者的生产力。 ##...

    利用hessian进行系统通信实例教程

    Hessian支持Java、C++、Python等多种编程语言,能够实现不同语言间的无缝通信。 二、Spring与Hessian的结合 Spring是一个广泛应用的开源Java框架,它提供了丰富的功能来简化企业级应用的开发。在Spring中集成...

    hessian简单实例

    - **跨语言支持**:Hessian不仅支持Java,还支持其他语言如C++,Python等,这使得多语言间的通信变得简单。 - **动态类型**:Hessian可以处理动态类型,无需预先定义复杂的接口或者数据结构。 - **透明性**:对于...

    Web Service Hessian 开发

    Hessian支持Java、C++、Python等多种语言,可以实现跨平台的通信。 二、Hessian服务端开发 在Java环境下,我们可以使用Caucho公司的Hessian库来创建Hessian服务。首先,我们需要定义一个服务接口,例如: ```java...

    基于spring+hessian框架的webservice实例

    Hessian支持多种语言,包括Java、C++、Python等,使得跨语言的交互成为可能。 在"基于spring+hessian框架的webservice实例"中,我们将看到如何结合Spring和Hessian来创建和消费Web服务。首先,我们需要创建一个服务...

    hessian与spring整合的jar包

    它支持Java、C++、Python等多种语言,常用于服务端和客户端之间的轻量级通信。 Spring框架是Java应用开发的核心框架,它提供了一个全面的编程和配置模型,简化了企业级应用的开发。Spring包含了许多模块,如核心...

    android端使用hessian跟web服务器通讯

    在Android应用开发中,与Web服务器进行通讯是常见的需求,Hessian是一种二进制协议,它使得Java和Java、Java和其他语言(如Python、C++)之间的远程调用变得高效且简便。本教程将深入探讨如何在Android端利用Hessian...

    Hessian例子.rar

    4. **跨语言支持**:虽然Hessian最初是为Java设计的,但后来也有了其他语言的实现,如C++、Python等。这意味着Hessian可以在不同的编程语言环境中工作,实现跨平台的通信。 5. **性能优化**:由于Hessian采用二进制...

Global site tag (gtag.js) - Google Analytics