Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: 处置WS命令时发生无法恢复的异常 #1328

Closed
3 tasks done
daizihan233 opened this issue Jan 14, 2022 · 8 comments
Closed
3 tasks done

[Bug]: 处置WS命令时发生无法恢复的异常 #1328

daizihan233 opened this issue Jan 14, 2022 · 8 comments
Labels
bug? The issue author think this is a bug

Comments

@daizihan233
Copy link

请确保您已阅读以上注意事项,并勾选下方的确认框。

  • 我已经仔细阅读上述教程和 "提问前需知"
  • 我已知晓并同意,如果我不遵循以下格式提交 Issue,或者我使用的并非最新版本,或者我没有提供足够的环境信息,我的 Issue 可能会被无条件自动关闭或/并锁定。
  • 我已知晓并同意,此处仅用于汇报程序中存在的问题。若这个 Issue 是关于其他非程序本身问题,则我的 Issue 可能会被无条件自动关闭或/并锁定。(这些问题应当在 Discussion 板块提出。)

go-cqhttp 版本

v1.0.0-beta8-fix2

运行环境

Windows (64)

运行架构

No response

连接方式

WebSocket (正向)

使用协议

0 | iPad

重现步骤

使用正向WebSocket与机器人链接,调用API时报错

期望的结果是什么?

正常发送一条消息给用户

实际的结果是什么?

go-cqhttp报错:
image
go-cqhttp返回:
image

简单的复现代码/链接(可选)

import json
import time

from websocket import create_connection

# 这个函数是抄百度的稍微改了一下返回API不存在
def websockets(url, headers_dict=None, params_dict=None, result: list = None):
    """
    websocket请求
    :param url:
    :param headers_dict:
    :param params_dict:
    :param result: 请求结果列表
    """
    print('websocket请求url:{}'.format(url))
    # step1 创建连接
    while True:
        try:
            if headers_dict is not None:
                ws = create_connection(url, headers=headers_dict)
            else:
                ws = create_connection(url)
            break
        except Exception as e:
            print('连接错误:{}'.format(e))
            time.sleep(5)
    print('请求是否成功:{}'.format('成' if ws.status == 101 else '失'))

    # step2请求/获取 响应
    for _ in range(2):  # 发送了两次请求因为第一次返回的信息不像是gocq的
        """
        第一次返回的信息:
        {'_post_method': 2, 'meta_event_type': 'lifecycle', 'post_type': 'meta_event', 'self_id': 748029973, 'sub_type': 'connect', 'time': 1642123760}
        """
        if params_dict is not None:
            params = params_dict
            ws.send(str(params))
        response = ws.recv()
        if result is not None:
            result.append(response)

    try:
        response = json.loads(response)
        print(response)
    except Exception:
        print('无法转为Dict')
    print('Type:', type(response))
    ws.close()
    return response

websockets(url='ws://127.0.0.1:6700/send_private_msg',
           params_dict={
               'user_id': 183713750,  # 给这个人发条消息
               'message': '2333'      #消息内容
           }
           )

日志记录(可选)

No response

补充说明(可选)

程序发送了两次请求,第一次请求gocq的日志显示:
image
不知道为啥参数后面没有任何东西

@daizihan233 daizihan233 added the bug? The issue author think this is a bug label Jan 14, 2022
@xiangxiangxiong9
Copy link
Contributor

试试把最后面的

websockets(url='ws://127.0.0.1:6700/send_private_msg',
           params_dict={
               'user_id': 183713750,  # 给这个人发条消息
               'message': '2333'      #消息内容
           }
           )

改成

websockets(url='ws://127.0.0.1:6700/',
           params_dict={'action': 'send_private_msg', 'params':{
               'user_id': 183713750,  # 给这个人发条消息
               'message': '2333'      #消息内容
           }}
           )

?

@daizihan233
Copy link
Author

还是不行
image

@daizihan233
Copy link
Author

(补充)有时候gocq也会输出这个
image

@daizihan233
Copy link
Author

(补充)有时候gocq也会输出这个 image

也就是“实际的结果是什么?”那一处的报错,有时候会有,有时候没有,但都提示找不到API

@xiangxiangxiong9
Copy link
Contributor

import aiohttp
import asyncio
async def func():
    async with aiohttp.ClientSession() as session:
        async with session.ws_connect('ws://127.0.0.1:6700/api') as ws:
            await ws.send_json({'action': 'send_private_msg', 'params':{
                   'user_id': 183713750,  # 给这个人发条消息
                   'message': '2333'      #消息内容
               }})
            data = await ws.receive_json()
    return data
asyncio.run(func())

这个呢??

@daizihan233
Copy link
Author

可以了,谢谢

@shadlc
Copy link

shadlc commented May 13, 2022

这里再提供一种不需要换aiohttp模块继续使用websocket模块的改法,之前的错误原因是因为单引号不是规范的json格式,cqhttp不识别,所以把

       params_dict={'action': 'send_private_msg', 'params':{
           'user_id': 183713750,  # 给这个人发条消息
           'message': '2333'      #消息内容
       }}

改为

       params_dict={"action": "send_private_msg", "params":{
           "user_id": 183713750,  # 给这个人发条消息
           "message": "2333"      #消息内容
       }}

这也是一种改法,websockets模块同理

@xiangxiangxiong9
Copy link
Contributor

xiangxiangxiong9 commented May 21, 2022

这里再提供一种不需要换aiohttp模块继续使用websocket模块的改法,之前的错误原因是因为单引号不是规范的json格式,cqhttp不识别,所以把

       params_dict={'action': 'send_private_msg', 'params':{
           'user_id': 183713750,  # 给这个人发条消息
           'message': '2333'      #消息内容
       }}

改为

       params_dict={"action": "send_private_msg", "params":{
           "user_id": 183713750,  # 给这个人发条消息
           "message": "2333"      #消息内容
       }}

这也是一种改法,websockets模块同理

应该是 把 ws.send(str(params)) 改为 ws.send(json.dumps(params, ensure_ascii=false)) 就行
应该是 python的dict 转换成 json 出了问题[不能直接str()]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug? The issue author think this is a bug
Projects
None yet
Development

No branches or pull requests

3 participants