lijunliang 9 tháng trước cách đây
mục cha
commit
b7dc26d1c7

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 10 - 0
.idea/a2s.iml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/venv" />
+    </content>
+    <orderEntry type="jdk" jdkName="Python 3.7 (awesome_extract)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 11 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,11 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <Languages>
+        <language minSize="161" name="Python" />
+      </Languages>
+    </inspection_tool>
+    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Black">
+    <option name="sdkName" value="Python 3.7 (awesome_extract)" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (awesome_extract)" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/a2s.iml" filepath="$PROJECT_DIR$/.idea/a2s.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 177 - 0
a2s.egg-info/PKG-INFO

@@ -0,0 +1,177 @@
+Metadata-Version: 2.1
+Name: a2s
+Version: 0.0.3
+Summary: A small example package
+Home-page: http://ai-01:8080/
+Author: LJL
+Author-email: author@example.com
+Classifier: Programming Language :: Python :: 3
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Description-Content-Type: text/markdown
+
+## **a2s服务的python工具包,更容易大规模应用**
+
+## *启动服务*
+
+```python
+# 使用前请安装工具包
+# pip install a2s
+# 下载地址:http://192.168.3.10:8080/simple/a2s/
+```
+
+```python
+from a2s.a2s_server import watch, simple_params
+
+
+# 方式一 使用简单方式启动   .py文件命令行参数   python server.py --h
+@simple_params
+@watch
+def main(data: bytes, *args, **kwargs) -> bytes:
+    '''
+
+    :param data: 固定格式,调用端发送的数据data
+    :param args: 固定格式
+    :param kwargs: 固定格式
+    :return: 返回调用端的 data
+    '''
+    # 内部处理程序
+    data = data.decode("utf-8")
+    data += "服务端处理过了数据"
+    return data.encode("utf-8")
+
+
+main()
+
+
+# 方式二 自定义启动方式
+@watch
+def main(data: bytes, *args, **kwargs) -> bytes:
+    '''
+
+    :param data: 固定格式,调用端发送的数据data
+    :param args: 固定格式
+    :param kwargs: 固定格式
+    :return:返回调用端的 data
+    '''
+    # 内部处理程序
+    data = data.decode("utf-8")
+    data += "服务端处理过了数据"
+    return data.encode("utf-8")
+
+
+main(nats_host="192.168.3.240", nats_port=19090, subject="test", queue="main")
+```
+
+#### 方式一 更简单方式启动
+
+#### 方法二 灵活性更高
+
+#### 推荐使用 *方法一*
+
+## *调用服务*
+
+a2s_client # 简化a2s客户端调用
+
+```python
+
+from a2s.a2s_client import a2s_execute
+
+if __name__ == '__main__':
+    # bytes_data 调用端的 data 记得编码
+    result = a2s_execute(a2s_ip="192.168.3.240:19094", topic="test", timeout=10, bytes_data=b"hello")
+    # result 服务端返回的 data 记得解码
+    print(result.decode("utf-8"))
+
+```
+
+## *监控*
+
+```python
+from a2s.a2s_monitor import watch_monitor
+
+service_count = watch_monitor('192.168.3.240:9090', 'goods_service')
+```
+
+## *工具*
+
+dict(字典) 序列化反序列化
+
+grpc 序列化反序列化
+
+```python
+
+import json
+import base64
+
+
+def grpc_serialize(resp):
+    """
+    grpc对象序列化
+    :param resp:resp = Text2VectorReq(text=data)
+    :return:
+    """
+    resp.SerializeToString()
+    return resp
+
+
+def grpc_deserialize(req, data):
+    """
+    grpc对象反序列化
+    :param req: req = Text2VectorResp()
+    :param data: req的序列化对象
+    :return:
+    """
+    req.ParseFromString(data)
+    return req
+
+
+def json_serialize(dict_data):
+    """
+    json对象序列化
+    :param resp: 字典
+    :return:
+    """
+    # 将字典转换为 JSON 格式的字符串
+    json_data = json.dumps(dict_data)
+
+    # 将 JSON 字符串转换为字节流
+    bytes_data = json_data.encode('utf-8')
+    return bytes_data
+
+
+def json_deserialize(bytes_data):
+    """
+    grpc对象反序列化
+    :param bytes_data:
+    :return:
+    """
+    # 将字节流转换为 JSON 字符串
+    json_data = bytes_data.decode('utf-8')
+
+    # 将 JSON 字符串转换为字典对象
+    dict_data = json.loads(json_data)
+    return dict_data
+
+# 二进制文件传输,json序列化解决方案:
+# 1. 将二进制文件转换为base64编码的字符串
+# 2. 将base64编码的字符串转换为二进制文件
+def binary_to_base64(binary_data):
+    """
+    二进制转化为base64字符串
+    :param binary_data:
+    :return:
+    """
+    base64_str = base64.b64encode(binary_data).decode('utf-8')  # 将bytes转换为base64字符串
+    return base64_str
+
+
+def base64_to_binary(base64_str):
+    """
+    base64字符串转化为二进制
+    :param base64_str:
+    :return:
+    """
+    binary_data = base64.b64decode(base64_str)  # 将base64字符串转换为bytes
+    return binary_data
+```

+ 20 - 0
a2s.egg-info/SOURCES.txt

@@ -0,0 +1,20 @@
+README.md
+setup.py
+a2s/__init__.py
+a2s/a2s_client.py
+a2s/a2s_monitor.py
+a2s/a2s_server.py
+a2s/tools.py
+a2s.egg-info/PKG-INFO
+a2s.egg-info/SOURCES.txt
+a2s.egg-info/dependency_links.txt
+a2s.egg-info/requires.txt
+a2s.egg-info/top_level.txt
+a2s/demo/__init__.py
+a2s/demo/client.py
+a2s/demo/monitor.py
+a2s/demo/server.py
+a2s/demo/test.py
+a2s/proto/__init__.py
+a2s/proto/service_pb2.py
+a2s/proto/service_pb2_grpc.py

+ 1 - 0
a2s.egg-info/dependency_links.txt

@@ -0,0 +1 @@
+

+ 4 - 0
a2s.egg-info/requires.txt

@@ -0,0 +1,4 @@
+nats-python
+grpcio
+grpcio-tools
+protobuf==3.19

+ 1 - 0
a2s.egg-info/top_level.txt

@@ -0,0 +1 @@
+a2s

+ 9 - 0
a2s/demo/test.py

@@ -0,0 +1,9 @@
+# coding:utf-8
+from pynats import NATSClient
+from a2s.tools import json_serialize
+
+# 创建 NATSClient 实例
+NatsIp = f"nats://172.17.4.188:19090"
+with NATSClient(NatsIp) as nc:
+    nc.connect()
+    nc.publish(subject="monitorRelease", payload=json_serialize({"host": "172.17.221.153"}))

+ 0 - 0
build/lib/a2s/__init__.py


+ 30 - 0
build/lib/a2s/a2s_client.py

@@ -0,0 +1,30 @@
+# coding:utf-8
+
+import grpc
+from a2s.proto import service_pb2, service_pb2_grpc
+import logging
+
+
+def a2s_execute(a2s_ip: str, topic: str, timeout: int, bytes_data: bytes):
+    """
+    a2e服务调用
+    :param a2s_ip: 192.168.3.240:9090  #  服务地址
+    :param topic: t2v   主体
+    :param timeout: 60  超时时间
+    :param bytes_data: 请求字段
+    :return: bytes or None
+    """
+    try:
+        if not (a2s_ip and topic):
+            raise IOError("参数错误:a2s_ip和topic不能为空!")
+        with grpc.insecure_channel(a2s_ip) as channel:
+            # 客户端实例
+            stub = service_pb2_grpc.CallerStub(channel)
+            # 调用服务端方法
+            response = stub.Call(service_pb2.Request(topic=topic, timeout=timeout, data=bytes_data))
+            # 获取结果
+            data = response.data
+            return data
+    except Exception as e:
+        logging.warning(e)
+        return None

+ 43 - 0
build/lib/a2s/a2s_monitor.py

@@ -0,0 +1,43 @@
+# coding:utf-8
+from a2s.proto import service_pb2
+from a2s.proto import service_pb2_grpc
+import grpc
+from pynats import NATSClient
+from a2s.tools import json_serialize
+
+
+def watch_monitor(a2s_ip, topic):
+    """
+    监控
+    :return:
+    """
+    try:
+        with grpc.insecure_channel(a2s_ip) as channel:
+            # 客户端实例
+            stub = service_pb2_grpc.CallerStub(channel)
+            # 调用服务端方法
+            response = stub.ViewState(service_pb2.StateReq(topic=topic))
+            # 反序列化
+            count = response.currentRequest
+            return count
+    except:
+        return None
+
+
+def close_worker(ip_list, a2s_ip, topic):
+    """
+    关闭worker
+    :param ip_list:
+    :param a2s_ip:
+    :param topic:
+    :return:
+    """
+    with NATSClient(a2s_ip, name=topic) as nc:
+        nc.connect()
+        try:
+            for host in ip_list:
+                nc.publish(subject=topic, payload=json_serialize({"host": host}))
+            return True
+        except Exception as e:
+            print(e)
+            return False

+ 101 - 0
build/lib/a2s/a2s_server.py

@@ -0,0 +1,101 @@
+# coding:utf-8
+import argparse
+from functools import wraps
+from pynats import NATSClient
+from a2s.proto.service_pb2 import NatsRequest, NatsResponse
+from a2s.tools import json_serialize, json_deserialize, get_host_ip
+import time
+import logging
+import uuid
+
+
+def callback():
+    pass
+
+
+def simple_params(func):
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('-host', '--nats_host', type=str, default="192.168.3.240", help='nats主机')
+        parser.add_argument('-port', '--nats_port', type=int, default=19090, help='nats端口')
+        parser.add_argument('-subject', '--subject', type=str, default="test", help='监听主题名称')
+        parser.add_argument('-manager_subject', '--manager_subject', type=str, help='监听关闭服务的主题')
+        parser.add_argument('-manager_queue', '--manager_queue', type=str, help='关闭服务的队列名称,推荐使用默认的uuid')
+        parser.add_argument('-server_host', '--server_host', type=str, help='关闭服务的队列名称,推荐使用默认的uuid')
+        parser.add_argument('-queue', '--queue', type=str, default="main", help='队列名称')
+        parser.add_argument('-minWorktime', '--min_worktime', type=int, default=0,
+                            help='用于修正超时时间,超时时间-min_worktime为真正的超时时间,减少无用的数据处理')
+        args = parser.parse_args()
+        params = dict(args._get_kwargs())
+        params.update(kwargs)
+        return func(**params)
+
+    return wrapper
+
+
+def watch(func):
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        nats_host = kwargs.get("nats_host")
+        nats_port = kwargs.get("nats_port")
+        subject = kwargs.get("subject")
+        manager_subject = kwargs.get("manager_subject")
+        manager_queue = uuid.uuid4().hex if not kwargs.get("manager_queue") else kwargs.get("manager_queue")
+        queue = kwargs.get("queue")
+        server_host = kwargs.get("server_host", None)
+        min_worktime = kwargs.get("min_worktime", 0)
+        call_back = kwargs.get("callback", callback)
+        if manager_subject and not server_host:
+            logging.warning("不知道你是否需要启用监控系统,因为你的server_host没有设置,监控系统将不会启用")
+        if not (nats_host and nats_port and subject and queue):
+            raise Exception("""
+建议使用:
+@simple_params
+@watch
+def main(data: bytes, *args, **kwargs) -> bytes:
+    """)
+        NatsIp = f"nats://{nats_host}:{nats_port}"
+        ListenSubject = subject + "_req"
+        PublishSubject = subject + "_resp"
+        logging.warning(
+            f"服务启动中>>>>listen::{ListenSubject}:,,publish:{PublishSubject},queue:{queue},manager:{manager_subject},manager_queue:{manager_queue},server_host:{server_host}")
+        with NATSClient(NatsIp, name=subject) as nc:
+            nc.connect()
+            worker_closed = False
+
+            def message_handler(msg):
+                try:
+                    nats_req = NatsRequest()
+                    nats_req.ParseFromString(msg.payload)
+                    #  检查消息是否超时
+                    t = int(time.time())
+                    if t - nats_req.timestamp >= nats_req.timeout - min_worktime:
+                        logging.debug("%s 这条消息超时了,舍弃" % (nats_req.msgId))
+                        return
+                    kwargs["data"] = nats_req.data
+                    bytes_result = func(*args, **kwargs)
+                    nats_resp = NatsResponse(msgId=nats_req.msgId, data=bytes_result)
+                    nc.publish(subject=PublishSubject, payload=nats_resp.SerializeToString())
+                    call_back()  # 回调函数,程序运行结束后执行的操作
+                except Exception as e:
+                    logging.warning(e)
+
+            def nodes_worker_closed(msg):
+                nonlocal worker
+                nonlocal worker_closed
+                close_msg = json_deserialize(msg.payload)
+                host = close_msg.get("host", None)
+                logging.warning(f"关闭服务节点Subject: {msg.subject}:::{msg.payload}::{host}::{server_host}")
+                if not worker_closed and host and host == server_host:
+                    nc.unsubscribe(worker)
+                    worker_closed = True
+                    logging.warning("订阅服务关闭成功......")
+
+            logging.warning(f"服务启动成功......")
+            worker = nc.subscribe(subject=ListenSubject, callback=message_handler, queue=queue)
+            if manager_subject:
+                work_manager = nc.subscribe(subject=manager_subject, callback=nodes_worker_closed, queue=manager_queue)
+            nc.wait()
+
+    return wrapper

+ 0 - 0
build/lib/a2s/demo/__init__.py


+ 10 - 0
build/lib/a2s/demo/client.py

@@ -0,0 +1,10 @@
+# coding:utf-8
+from a2s.a2s_client import a2s_execute
+import time
+
+if __name__ == '__main__':
+    for i in range(20):
+        print("开始第%d次发送"%i)
+        result = a2s_execute(a2s_ip="192.168.3.240:9090", topic="test1", timeout=6, bytes_data=b"hello")
+        print(result.decode("utf-8"))
+        print("结束第%d次发送"%i)

+ 11 - 0
build/lib/a2s/demo/monitor.py

@@ -0,0 +1,11 @@
+from a2s.a2s_monitor import watch_monitor
+
+if __name__ == '__main__':
+    import time
+
+    for i in range(1000):
+        ner_count = watch_monitor('192.168.3.240:9090', 'goods_ner')
+        field_count = watch_monitor('192.168.3.240:9090', 'goods_field')
+        service_count = watch_monitor('192.168.3.240:9090', 'goods_service')
+        print("service_count:", service_count, "ner_count:", ner_count, "field_count:", field_count)
+        time.sleep(0.5)

+ 28 - 0
build/lib/a2s/demo/server.py

@@ -0,0 +1,28 @@
+from a2s.a2s_server import watch, simple_params
+import time
+
+#方式一 使用简单方式启动   .py文件命令行参数   python server.py --h
+@simple_params
+@watch
+def main(data: bytes, *args, **kwargs) -> bytes:
+    '''
+
+    :param data: 固定格式
+    :param args: 固定格式
+    :param kwargs: 固定格式
+    :return:
+    '''
+    # 内部处理程序
+    print("服务端运行中")
+    data = data.decode("utf-8")
+    data += "test1服务端处理过了数据"
+    time.sleep(10)
+    return data.encode("utf-8")
+
+import sys
+def callback():
+    print("运行结束")
+    sys.exit(1)
+
+if __name__ == '__main__':
+    main(subject="test1")

+ 9 - 0
build/lib/a2s/demo/test.py

@@ -0,0 +1,9 @@
+# coding:utf-8
+from pynats import NATSClient
+from a2s.tools import json_serialize
+
+# 创建 NATSClient 实例
+NatsIp = f"nats://172.17.4.188:19090"
+with NATSClient(NatsIp) as nc:
+    nc.connect()
+    nc.publish(subject="monitorRelease", payload=json_serialize({"host": "172.17.221.153"}))

+ 0 - 0
build/lib/a2s/proto/__init__.py


+ 353 - 0
build/lib/a2s/proto/service_pb2.py

@@ -0,0 +1,353 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: service.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='service.proto',
+  package='main',
+  syntax='proto3',
+  serialized_options=b'Z\005.;a2s',
+  serialized_pb=b'\n\rservice.proto\x12\x04main\"7\n\x07Request\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0f\n\x07timeout\x18\x02 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"3\n\x08Response\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0b\n\x03msg\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x19\n\x08StateReq\x12\r\n\x05topic\x18\x01 \x01(\t\"#\n\tStateResp\x12\x16\n\x0e\x63urrentRequest\x18\x01 \x01(\x05\"N\n\x0bNatsRequest\x12\r\n\x05msgId\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0f\n\x07timeout\x18\x03 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\"+\n\x0cNatsResponse\x12\r\n\x05msgId\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x32\x61\n\x06\x43\x61ller\x12\'\n\x04\x43\x61ll\x12\r.main.Request\x1a\x0e.main.Response\"\x00\x12.\n\tViewState\x12\x0e.main.StateReq\x1a\x0f.main.StateResp\"\x00\x42\x07Z\x05.;a2sb\x06proto3'
+)
+
+
+
+
+_REQUEST = _descriptor.Descriptor(
+  name='Request',
+  full_name='main.Request',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topic', full_name='main.Request.topic', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeout', full_name='main.Request.timeout', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='main.Request.data', index=2,
+      number=3, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=23,
+  serialized_end=78,
+)
+
+
+_RESPONSE = _descriptor.Descriptor(
+  name='Response',
+  full_name='main.Response',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='main.Response.code', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='msg', full_name='main.Response.msg', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='main.Response.data', index=2,
+      number=3, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=80,
+  serialized_end=131,
+)
+
+
+_STATEREQ = _descriptor.Descriptor(
+  name='StateReq',
+  full_name='main.StateReq',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topic', full_name='main.StateReq.topic', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=133,
+  serialized_end=158,
+)
+
+
+_STATERESP = _descriptor.Descriptor(
+  name='StateResp',
+  full_name='main.StateResp',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='currentRequest', full_name='main.StateResp.currentRequest', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=160,
+  serialized_end=195,
+)
+
+
+_NATSREQUEST = _descriptor.Descriptor(
+  name='NatsRequest',
+  full_name='main.NatsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='msgId', full_name='main.NatsRequest.msgId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='main.NatsRequest.timestamp', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeout', full_name='main.NatsRequest.timeout', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='main.NatsRequest.data', index=3,
+      number=4, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=197,
+  serialized_end=275,
+)
+
+
+_NATSRESPONSE = _descriptor.Descriptor(
+  name='NatsResponse',
+  full_name='main.NatsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='msgId', full_name='main.NatsResponse.msgId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='main.NatsResponse.data', index=1,
+      number=4, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=277,
+  serialized_end=320,
+)
+
+DESCRIPTOR.message_types_by_name['Request'] = _REQUEST
+DESCRIPTOR.message_types_by_name['Response'] = _RESPONSE
+DESCRIPTOR.message_types_by_name['StateReq'] = _STATEREQ
+DESCRIPTOR.message_types_by_name['StateResp'] = _STATERESP
+DESCRIPTOR.message_types_by_name['NatsRequest'] = _NATSREQUEST
+DESCRIPTOR.message_types_by_name['NatsResponse'] = _NATSRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Request = _reflection.GeneratedProtocolMessageType('Request', (_message.Message,), {
+  'DESCRIPTOR' : _REQUEST,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.Request)
+  })
+_sym_db.RegisterMessage(Request)
+
+Response = _reflection.GeneratedProtocolMessageType('Response', (_message.Message,), {
+  'DESCRIPTOR' : _RESPONSE,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.Response)
+  })
+_sym_db.RegisterMessage(Response)
+
+StateReq = _reflection.GeneratedProtocolMessageType('StateReq', (_message.Message,), {
+  'DESCRIPTOR' : _STATEREQ,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.StateReq)
+  })
+_sym_db.RegisterMessage(StateReq)
+
+StateResp = _reflection.GeneratedProtocolMessageType('StateResp', (_message.Message,), {
+  'DESCRIPTOR' : _STATERESP,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.StateResp)
+  })
+_sym_db.RegisterMessage(StateResp)
+
+NatsRequest = _reflection.GeneratedProtocolMessageType('NatsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _NATSREQUEST,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.NatsRequest)
+  })
+_sym_db.RegisterMessage(NatsRequest)
+
+NatsResponse = _reflection.GeneratedProtocolMessageType('NatsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _NATSRESPONSE,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:main.NatsResponse)
+  })
+_sym_db.RegisterMessage(NatsResponse)
+
+
+DESCRIPTOR._options = None
+
+_CALLER = _descriptor.ServiceDescriptor(
+  name='Caller',
+  full_name='main.Caller',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=322,
+  serialized_end=419,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Call',
+    full_name='main.Caller.Call',
+    index=0,
+    containing_service=None,
+    input_type=_REQUEST,
+    output_type=_RESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ViewState',
+    full_name='main.Caller.ViewState',
+    index=1,
+    containing_service=None,
+    input_type=_STATEREQ,
+    output_type=_STATERESP,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CALLER)
+
+DESCRIPTOR.services_by_name['Caller'] = _CALLER
+
+# @@protoc_insertion_point(module_scope)

+ 98 - 0
build/lib/a2s/proto/service_pb2_grpc.py

@@ -0,0 +1,98 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import a2s.proto.service_pb2 as service__pb2
+
+
+class CallerStub(object):
+    """Missing associated documentation comment in .proto file"""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Call = channel.unary_unary(
+                '/main.Caller/Call',
+                request_serializer=service__pb2.Request.SerializeToString,
+                response_deserializer=service__pb2.Response.FromString,
+                )
+        self.ViewState = channel.unary_unary(
+                '/main.Caller/ViewState',
+                request_serializer=service__pb2.StateReq.SerializeToString,
+                response_deserializer=service__pb2.StateResp.FromString,
+                )
+
+
+class CallerServicer(object):
+    """Missing associated documentation comment in .proto file"""
+
+    def Call(self, request, context):
+        """远程调用
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ViewState(self, request, context):
+        """状态查看
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_CallerServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Call': grpc.unary_unary_rpc_method_handler(
+                    servicer.Call,
+                    request_deserializer=service__pb2.Request.FromString,
+                    response_serializer=service__pb2.Response.SerializeToString,
+            ),
+            'ViewState': grpc.unary_unary_rpc_method_handler(
+                    servicer.ViewState,
+                    request_deserializer=service__pb2.StateReq.FromString,
+                    response_serializer=service__pb2.StateResp.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'main.Caller', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Caller(object):
+    """Missing associated documentation comment in .proto file"""
+
+    @staticmethod
+    def Call(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/main.Caller/Call',
+            service__pb2.Request.SerializeToString,
+            service__pb2.Response.FromString,
+            options, channel_credentials,
+            call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ViewState(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/main.Caller/ViewState',
+            service__pb2.StateReq.SerializeToString,
+            service__pb2.StateResp.FromString,
+            options, channel_credentials,
+            call_credentials, compression, wait_for_ready, timeout, metadata)

+ 93 - 0
build/lib/a2s/tools.py

@@ -0,0 +1,93 @@
+# coding:utf-8
+import json
+import socket
+import base64
+
+
+def get_host_ip():
+    """
+    获取本机ip
+    :return:
+    """
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        s.connect(('8.8.8.8', 80))
+        ip = s.getsockname()[0]
+    finally:
+        s.close()
+
+    return ip
+
+
+def grpc_serialize(resp):
+    """
+    grpc对象序列化
+    :param resp:resp = Text2VectorReq(text=data)
+    :return:
+    """
+    strint_resp = resp.SerializeToString()
+    return strint_resp
+
+
+def grpc_deserialize(req, data):
+    """
+    grpc对象反序列化
+    :param req: req = Text2VectorResp()
+    :param data: req的序列化对象
+    :return:
+    """
+    req.ParseFromString(data)
+    return req
+
+
+def json_serialize(dict_data):
+    """
+    json对象序列化
+    :param resp: 字典
+    :return:
+    """
+    # 将字典转换为 JSON 格式的字符串
+    json_data = json.dumps(dict_data, ensure_ascii=False)
+
+    # 将 JSON 字符串转换为字节流
+    bytes_data = json_data.encode('utf-8')
+    return bytes_data
+
+
+def json_deserialize(bytes_data):
+    """
+    grpc对象反序列化
+    :param bytes_data:
+    :return:
+    """
+    # 将字节流转换为 JSON 字符串
+    json_data = bytes_data.decode('utf-8')
+
+    # 将 JSON 字符串转换为字典对象
+    dict_data = json.loads(json_data)
+    return dict_data
+
+
+def binary_to_base64(binary_data):
+    """
+    二进制转化为base64字符串
+    :param binary_data:
+    :return:
+    """
+    base64_str = base64.b64encode(binary_data).decode('utf-8')  # 将bytes转换为base64字符串
+    return base64_str
+
+
+def base64_to_binary(base64_str):
+    """
+    base64字符串转化为二进制
+    :param base64_str:
+    :return:
+    """
+    binary_data = base64.b64decode(base64_str)  # 将base64字符串转换为bytes
+    return binary_data
+
+
+if __name__ == '__main__':
+    a = binary_to_base64(open("./a2s_monitor.py", "rb").read())
+    print(a)

BIN
dist/a2s-0.0.3-py3-none-any.whl


BIN
dist/a2s-0.0.3.tar.gz