我可以访问QtWebEngine';没有QWebChannel的基础IPC是什么?
QtWebEngine使用IPC机制在C+Qt世界和JavaScript工作之间进行通信。此机制用于QWebChannel,并且似乎基于WebSocket。有没有一种方法可以在不使用QWebChannel的情况下使用底层IPC或WebSocket,因为后者似乎仅限于字符串或JSON编码的数据 背景:我编写了一个应用程序,它是一个基于JavaScript的终端仿真器,使用QWebChannel将PTY的输入/输出连接到QtWebEngine。这工作得相当好,但有一个与utf8/字符串转换相关的小故障。理想情况下,我希望从PTY发送原始字节,并用JavaScript进行字节到文本的转换。但QWebChannel的级别太高,只能处理字符串或JSON编码的数据。它不处理QByteArray 当然,有多种方法可以解决我的问题。一种是手动创建WebSocket服务器,并让运行在QtWebEngine中的JavaScript连接到它。但不管怎样,这似乎就是幕后正在发生的事情,使用我可以访问QtWebEngine';没有QWebChannel的基础IPC是什么?,qt,websocket,qbytearray,qtwebengine,Qt,Websocket,Qbytearray,Qtwebengine,QtWebEngine使用IPC机制在C+Qt世界和JavaScript工作之间进行通信。此机制用于QWebChannel,并且似乎基于WebSocket。有没有一种方法可以在不使用QWebChannel的情况下使用底层IPC或WebSocket,因为后者似乎仅限于字符串或JSON编码的数据 背景:我编写了一个应用程序,它是一个基于JavaScript的终端仿真器,使用QWebChannel将PTY的输入/输出连接到QtWebEngine。这工作得相当好,但有一个与utf8/字符串转换相关的小故
qt.webChannelTransport
。如果我能够访问底层传输(类WebChannelIPCTransportHost
似乎是相关的),那么它看起来将是最高效、最优雅的
有人试过这样的吗?也就是说,我不想使用QWebChannel,除非有一种有效的方式让它通过QByteArray
(我重新表述了这个问题。有一条关于缺少研究的评论,但我已经仔细浏览了Qt文档、源代码和这里,没有找到明确的答案。)是什么阻止你发送
QString::fromLatin1(data.toHex())
,其中数据属于QByteArray
类型?这就是你所需要的,真的。在javascript端使用反向转换,例如,请参见..,因为似乎没有一种方法可以“在”QWebChannel下面(不攻击Qt本身),所以似乎有三个选项:
- 创建单独的WebSocket连接。这将需要更大的非本地更改,并可能创建额外的进程
> P>在C++侧进行字节到文本解码,可能使用QTraceDelphi。这可能是最简单的。然而,有一些架构上的原因使我们更倾向于在我们进行转义序列处理的地方进行文本解码。这当然更传统,而且可能更好地处理角落案件。另外,除了QtDomTerm前端,DomTerm还需要与其他前端一起工作
- 将ByTestStream编码为字符串序列,使用QWebChannel传输后者,在JavaScript端转换回字节,然后用JavaScript处理文本解码
我选择实施第三个选项。在转换后端的过程中会有一些开销。但是,我设计并实现了一种非常有效的编码:
/** Encode an arbitrary sequence of bytes as an ASCII string.
* This is used because QWebChannel doesn't have a way to transmit
* data except as strings or JSON-encoded strings.
* We restrict the encoding to ASCII (i.e. codes less then 128)
* to avoid excess bytes if the result is UTF-8-encoded.
*
* The encoding optimizes UTF-8 data, with the following byte values:
* 0-3: 1st byte of a 2-byte sequence encoding an arbitrary 8-bit byte.
* 4-7: 1st byte of a 2-byte sequence encoding a 2-byte UTF8 Latin-1 character.
* 8-13: mean the same ASCII control character
* 14: special case for ESC
* 15: followed by 2 more bytes encodes a 2-byte UTF8 sequence.
* bytes 16-31: 1st byte of a 3-byte sequence encoding a 3-byte UTF8 sequence.
* 32-127: mean the same ASCII printable character
* The only times we generate extra bytes for a valid UTF8 sequence
* if for code-points 0-7, 14-26, 28-31, 0x100-0x7ff.
* A byte that is not part of a valid UTF9 sequence may need 2 bytes.
* (A character whose encoding is partial, may also need extra bytes.)
*/
static QString encodeAsAscii(const char * buf, int len)
{
QString str;
const unsigned char *ptr = (const unsigned char *) buf;
const unsigned char *end = ptr + len;
while (ptr < end) {
unsigned char ch = *ptr++;
if (ch >= 32 || (ch >= 8 && ch <= 13)) {
// Characters in the printable ascii range plus "standard C"
// control characters are encoded as-is
str.append(QChar(ch));
} else if (ch == 27) {
// Special case for ESC, encoded as '\016'
str.append(QChar(14));
} else if ((ch & 0xD0) == 0xC0 && end - ptr >= 1
&& (ptr[0] & 0xC0) == 0x80) {
// Optimization of 2-byte UTF-8 sequence
if ((ch & 0x1C) == 0) {
// If Latin-1 encode 110000aa,10bbbbbb as 1aa,0BBBBBBB
// where BBBBBBB=48+bbbbbb
str.append(4 + QChar(ch & 3));
} else {
// Else encode 110aaaaa,10bbbbbb as '\017',00AAAAA,0BBBBBBB
// where AAAAAA=48+aaaaa;BBBBBBB=48+bbbbbb
str.append(QChar(15));
str.append(QChar(48 + (ch & 0x3F)));
}
str.append(QChar(48 + (*ptr++ & 0x3F)));
} else if ((ch & 0xF0) == 0xE0 && end - ptr >= 2
&& (ptr[0] & 0xC0) == 0x80 && (ptr[1] & 0xC0) == 0x80) {
// Optimization of 3-byte UTF-8 sequence
// encode 1110aaaa,10bbbbbb,10cccccc as AAAA,0BBBBBBB,0CCCCCCC
// where AAAA=16+aaaa;BBBBBBB=48+bbbbbb;CCCCCCC=48+cccccc
str.append(QChar(16 + (ch & 0xF)));
str.append(QChar(48 + (*ptr++ & 0x3F)));
str.append(QChar(48 + (*ptr++ & 0x3F)));
} else {
// The fall-back case - use 2 bytes for 1:
// encode aabbbbbb as 000000aa,0BBBBBBB, where BBBBBBB=48+bbbbbb
str.append(QChar((ch >> 6) & 3));
str.append(QChar(48 + (ch & 0x3F)));
}
}
return str;
}
/**将任意字节序列编码为ASCII字符串。
*这是因为QWebChannel没有传输方式
*除字符串或JSON编码字符串以外的数据。
*我们将编码限制为ASCII码(即小于128码)
*如果结果是UTF-8编码的,则避免多余字节。
*
*编码使用以下字节值优化UTF-8数据:
*0-3:编码任意8位字节的2字节序列的第一个字节。
*4-7:编码2字节UTF8拉丁-1字符的2字节序列的第一个字节。
*8-13:表示相同的ASCII控制字符
*14:ESC的特殊情况
*15:后跟2个字节编码2字节UTF8序列。
*字节16-31:编码3字节UTF8序列的3字节序列的第一个字节。
*32-127:表示相同的ASCII可打印字符
*我们为有效的UTF8序列生成额外字节的唯一次数
*如果用于代码点0-7、14-26、28-31、0x100-0x7ff。
*不属于有效UTF9序列的字节可能需要2个字节。
*(编码为部分编码的字符也可能需要额外的字节。)
*/
静态QString encodeAsasii(常量字符*buf,整数长度)
{
QString-str;
常量无符号字符*ptr=(常量无符号字符*)buf;
常量无符号字符*end=ptr+len;
while(ptr=32 | |(ch>=8&&ch=1
&&(ptr[0]&0xC0)==0x80){
//2字节UTF-8序列的优化
如果((ch&0x1C)==0){
//如果拉丁语-1将110000aa、10bbbbbb编码为1aa、0BBBBB
//式中,bbb=48+bbbbbb
str.append(4+QChar(ch&3));
}否则{
//否则将110AAAA、10bbbbbb编码为'\017',00AAAA、0BBBBB
//其中AAAAAA=48+aaaaa;BBBBBBB=48+bbbbbb
str.append(QChar(15));
str.append(QChar(48+(ch&0x3F));
}
str.append(QChar(48+(*ptr++&0x3F));
}如果((ch&0xF0)=0xE0&&end-ptr>=2,则为else
&&(ptr[0]&0xC0)==0x80&&(ptr[1]&0xC0)==0x80){
//3字节UTF-8序列的优化
//将1110aaaa、10bbbbbb、10cccccc编码为AAAA、0BBBBBBB、0CCCCCC
//其中AAAA=16+AAAA;BBBBB=48+bbbbbb;CCCCCCC=48+CCCCC
str.append(QChar(16+(ch&0xF));
str.append(QChar(48+(*ptr++&0x3F));
str.append(QChar(48+(*ptr++&0x3F));
}否则{
//回退案例-使用2个字节表示1:
//将aabbbb编码为000000 aa,0bbbbb,其中bbbbb=48+bbbbb
str.append(QChar((ch>>6)和3));
str.append(QChar(48+(ch&0x3F));
}
}
返回str;
}
是的,这是过分的,而且几乎肯定是过早的优化,但我不能控制自己:-)是的,将字节转换为十六进制并传输结果字符串肯定是可行的(而且相对简单)。但不可否认,它效率低下,因为它将传输的数据量增加了一倍。这也冒犯了我的朋友