- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为演示创建一个简单的双协议(protocol)客户端和服务器。但是当我在 websocket 的客户端初始化中指定两个子协议(protocol)时,我总是在服务器端收到此消息:
[1363089953:1535] ERR: Req protocol SIGN_IN_OUT_REQUEST_PROTOCOL, GET_REQUEST_PROTOCOL not supported
客户端 Javascript 代码:
var host = 'ws://10.0.96.32:9000';
var webSocket = {};
var websocketStatus = {};
$(function() {
function webSocketSupported() {
if(window.MozWebSocket) {
window.WebSocket = window.MozWebSocket;
}
return (window.webSocket != null);
}
if(!webSocketSupported) {
$(document).simpledialog2({
mode: 'blank',
headerClose: true,
blankContent :
"<p>Websockets not supported by this browser. How about <a href='http://www.google.com/chrome'>Google Chrome</a>?</p>"+
"<a rel='close' data-role='button' href='#'>Close</a>"
});
} else {
$("#login_form").validate({
rules:{
username: {required: true, minlength: 2},
password: {required: true, minlength: 4}
},
messages:{
username: {required: "Username is required",
minlength: "Username must be atleast 2 characters"},
password: {required: "Password is required",
minlength: "Password must be atleast 4 characters"}
}
});
/** Setting up WebSocket **/
webSocket = new WebSocket(host, 'SIGN_IN_OUT_REQUEST_PROTOCOL', 'GET_REQUEST_PROTOCOL');
webSocket.binaryType = "arraybuffer";
webSocket.onopen = onopen;
webSocket.onmessage = onmessage;
webSocket.onclose = onclose;
webSocket.onerror = onerror;
}
});
function onopen() {
$('#connectionStatus').text("Connected");
$('#connectionStatus').buttonMarkup({theme: 'b'});
$("#connectionStatus").data('icon', 'check');
$("#connectionStatus .ui-icon").addClass("ui-icon-check").removeClass("ui-icon-alert");
$('#login_info').append("Sub-protocol: "+webSocket.protocol+"\n");
}
function onmessage(event) {
var data = new DataView(event.data);
if(data.getUint8(data.byteLength - 1) == 1) {
$('#login_info').append("Login Attempt Successful");
$.mobile.loadPage("mobileApp.html");
$.mobile.changePage("mobileApp.html")
}
else {
$('#login_info').append("Login Attempt Unsuccessful");
$('#username').val("");
$('#password').val("");
}
}
function onclose() {
$('#connectionStatus').text("Connection Closed");
$('#connectionStatus').buttonMarkup({theme: 'a'});
$("#connectionStatus").data('icon', 'alert');
$("#connectionStatus .ui-icon").addClass("ui-icon-alert").removeClass("ui-icon-alert");
}
function onerror() {
$('#connectionStatus').text("Connection Error");
$('#connectionStatus').buttonMarkup({theme: 'a'});
$("#connectionStatus").data('icon', 'alert');
$("#connectionStatus .ui-icon").addClass("ui-icon-alert").removeClass("ui-icon-alert");
}
function initialize() {
$('#login_info').val("");
$('#username').val("");
$('#password').val("");
$('#connectionStatus').text("Connection Closed");
$('#connectionStatus').buttonMarkup({theme: 'a'});
$("#connectionStatus").data('icon', 'alert');
$("#connectionStatus .ui-icon").addClass("ui-icon-alert").removeClass("ui-icon-alert");
}
function sendLoginRequest(event) {
var i = 0;
event.preventDefault();
if($("#login_form").valid()) {
var username = $("#username").val();
var password = $("#password").val();
var loginRequest = new Uint8Array(calculateBufferLength());
loginRequest[i++] = 0x13; //User Accounts IP
loginRequest[i++] = 0x13; //Sign In/Sign Out Request
loginRequest[i++] = 0x07; //Sign In
loginRequest[i++] = username.length;
loginRequest[i++] = password.length;
//Pushing username
for(var j=0; j < username.length; j++) {
loginRequest[i++] = username.charCodeAt(j);
}
//Pushing password
for(var j=0; j < password.length; j++) {
loginRequest[i++] = password.charCodeAt(j);
}
webSocket.send(loginRequest.buffer);
$("#login_info").append("Login request sent with\nUsername: "+username+"\nPassword: "+password+"\n");
}
}
function calculateBufferLength() {
var opIPLength = 1;
var modeLength = 1;
var subModeLength = 1;
var UserNamePasswordlengths = 2;
var userNameLength = $("#username").val().length;
var passwordLength = $("#password").val().length;
return (opIPLength + modeLength + subModeLength + UserNamePasswordlengths + userNameLength + passwordLength);
}
服务器 C/C++ 代码 (Libwebsockets)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string>
#include <vector>
#include <libwebsockets.h>
using namespace std;
typedef enum {
USER_ACCOUNTS_IP_REQUEST,
MODE,
SUB_MODE,
USER_NAME_LENGTH,
PASSWORD_LENGTH
}user_accounts_ip_request_t;
typedef enum {
USER_ACCOUNTS_IP_RESPONSE,
RESPONSE_IP
}user_accounts_ip_response_t;
int Hex_to_Dec(unsigned char *array, int size);
void sendLoginResponse(struct libwebsocket *wsi, void *in_buffer, size_t bufferlen, struct per_session_data__binary *out_buffer);
void printSocketInfo(struct libwebsocket *wsi, struct libwebsocket_context *currentContext);
struct per_session_data__binary
{
unsigned int len;
unsigned char buf[sizeof(LWS_SEND_BUFFER_PRE_PADDING) + 1024 + sizeof(LWS_SEND_BUFFER_POST_PADDING)];
};
static int callback_http(struct libwebsocket_context *currentContext,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len)
{
return 0;
}
static int callback_sign_in_out_request(struct libwebsocket_context *currentContext,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
{
struct per_session_data__binary *psb = (per_session_data__binary *)user; ////////
switch (reason) {
case LWS_CALLBACK_ESTABLISHED: // just log message that someone is connecting
printf("connection established\n");
break;
case LWS_CALLBACK_PROTOCOL_INIT:
printf("LWS_CALLBACK_PROTOCOL_INIT\n");
break;
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
printf("LWS_CALLBACK_CLIENT_CONNECTION_ERROR\n");
break;
case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
printf("LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH\n");
break;
case LWS_CALLBACK_RECEIVE: {
printf("Binary frame received decoding packet...\n");
sendLoginResponse(wsi, in, len, psb);
}
break;
default:
break;
}
return 0;
}
static int callback_get_request(struct libwebsocket_context *currentContext,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
{
return 0;
}
static struct libwebsocket_protocols protocols[] = {
/* first protocol must always be HTTP handler */
{
"http-only", // name
callback_http, // callback
0 // per_session_data_size
},
{
"SIGN_IN_OUT_REQUEST_PROTOCOL", // protocol name - very important!
callback_sign_in_out_request, // callback
sizeof(struct per_session_data__binary) // we don't use any per session data
},
{
"GET_REQUEST_PROTOCOL",
callback_get_request,
sizeof(struct per_session_data__binary)
},
{
NULL, NULL, 0 /* End of list */
}
};
int main(void) {
// server url will be http://localhost:9000
int port = 9000;
const char *interface = NULL;
struct libwebsocket_context *context;
struct lws_context_creation_info info;
// we're not using ssl
const char *cert_path = NULL;
const char *key_path = NULL;
// no special options
int opts = 0;
info.port = port;
info.iface = interface;
info.protocols = protocols;
info.extensions = libwebsocket_get_internal_extensions();
info.ssl_cert_filepath = cert_path;
info.ssl_private_key_filepath = key_path;
info.ssl_ca_filepath = NULL;
info.gid = -1;
info.uid = -1;
info.options = opts;
info.user = NULL;
//info.ka_time = 0;
//info.ka_probes = 100;
//info.ka_interval= 60;
context = libwebsocket_create_context(&info);
if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n");
return -1;
}
printf("starting server...\n");
// infinite loop, to end this server send SIGTERM. (CTRL+C)
while (1) {
libwebsocket_service(context, 50);
//printf("after service\n");
// libwebsocket_service will process all waiting events with their
// callback functions and then wait 50 ms.
// (this is a single threaded webserver and this will keep our server
// from generating load while there are not requests to process)
}
libwebsocket_context_destroy(context);
return 0;
}
void sendLoginResponse(struct libwebsocket *wsi, void *in_buffer, size_t bufferlen, struct per_session_data__binary *out_buffer)
{
vector<string> userNames, passwords;
string userName, password;
bool loginValid = false;
int usernameLength, passwordLength;
int usernamePos, passwordPos;
userNames.push_back("Nautel");
passwords.push_back("password");
//Print Login Request Data
char* loginRequest = (char*) in_buffer;
usernameLength = loginRequest[USER_NAME_LENGTH];
passwordLength = loginRequest[PASSWORD_LENGTH];
usernamePos = PASSWORD_LENGTH + 1;
passwordPos = usernamePos + usernameLength;
//Get Username
for(int i=usernamePos; i < (usernamePos+usernameLength); i++) {
userName.push_back(loginRequest[i]);
}
//Get Password
for(int i=passwordPos; i < (passwordPos + passwordLength); i++) {
password.push_back(loginRequest[i]);
}
printf("Username: %s Password: %s\n", userName.c_str(), password.c_str());
for(int i=0; i < userNames.size(); i++) {
loginValid = (!userName.compare(userNames[i]) && !password.compare(passwords[i]));
if(loginValid) break;
}
out_buffer->buf[USER_ACCOUNTS_IP_RESPONSE] = 0x13;
out_buffer->buf[RESPONSE_IP] = (loginValid) ? 0x01 : 0x00;
out_buffer->len = 2;
libwebsocket_write(wsi, out_buffer->buf, out_buffer->len, LWS_WRITE_BINARY);
}
void printSocketInfo(struct libwebsocket *wsi, struct libwebsocket_context *currentContext){
char name[128];
int name_len=sizeof(name);
char rip[16];
int rip_len= sizeof(rip);
int fd;
fd = libwebsocket_get_socket_fd(wsi);
libwebsockets_get_peer_addresses (currentContext, wsi, fd, name, name_len, rip, rip_len);
printf("Name: %s, IP: %s\n", name, rip);
}
是否有可能让具有多个子协议(protocol)的客户端由单个服务器支持,反之亦然。或者我是否需要从客户端到服务器的多个 websocket 连接以用于不同的协议(protocol)。
问候,史瑞亚斯
最佳答案
WebSocket 客户端可以宣布支持多个 WebSocket 子协议(protocol),但服务器必须从客户端宣布的列表中选择一个(它支持的)子协议(protocol)。
关于javascript - 多个子协议(protocol) Websocket Javascript 客户端和 Libwebsockets 服务器不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15361105/
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!