求一个websocket

已解决  已打赏  
xx xx  悬赏: 5 金币
发布:2017-06-15 11:11:49 分类:问答
在别的地方下载了这个库,运行时出错
import win.guid;
import crypt.bin;
import inet.url;
import wsock.tcp.client;

namespace web{
class socket{
ctor(url, options){
//For debugger
this.traceEnabled = false;

this._url = url;
this._options = options;
this._socket = ..wsock.tcp.client();
if(!this._socket){
return null,"Create websocket client failed.";
}

this.version = 13;
this.connect_state = 0/*_WEBS_CONNECTING*/;
this.header_protocol = "";
this.header_extensions = "";
this.buffered_amount = 0;
this.binary_type = 2/*_WEBS_BINARYTYPE_ARRAYBUFFER*/;

HEADER_END_SIGN = '\r\n\r\n';
HEADER_VALIDATE_KEY = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';

LENGTH_7 = 0x7d;
LENGTH_16 = 1 << 16;
LENGTH_63 = ..math.abs(1 << 63);

OPCODES = {0/*_WEBS_OPCODE_CONT*/; 1/*_WEBS_OPCODE_TEXT*/; 2/*_WEBS_OPCODE_BINARY*/;
8/*_WEBS_OPCODE_CLOSE*/; 9/*_WEBS_OPCODE_PING*/; 0xA/*_WEBS_OPCODE_PONG*/}
//Masked the data by a random number
this._masked = function(mask_key, data){
var toArray = function(str){
var tmp = {};
for(i=1;#str;1){
var chr = ..string.sub(str,i,i);
if(chr){
..table.push(tmp, chr);
}
}
return tmp;
}
var _m = toArray(tostring(mask_key));
var _d = toArray(data);
for(i=1;#_d;1){
_d[i] = ..string.unpack(_d[i])^..string.unpack(_m[((i-1) % 4) +1]);
}
return ..string.pack(_d);
};
//Connected websocket server must handshake at first.
this._handshake = function(host, port, resource, options){
var validate_header = function(acceptKey, key){
var sha1 = ..crypt.sha1(key++HEADER_VALIDATE_KEY);
var tmp = {};
for(i=1;#sha1;2){
var num = tonumber(..string.sub(sha1,i,i+1),16);
..table.push(tmp,num);
}
var vkey = ..crypt.bin.encodeBase64(..string.pack(tmp));
if(acceptKey && ..string.lower(acceptKey) == ..string.lower(vkey)){
return true;
}
return false;
};

var headers = {};
..table.push(headers,..string.format("GET %s HTTP/1.1", resource), "Upgrade: websocket", "Connection: Upgrade");
if(port == 80){
hostport = host;
}else{
hostport = ..string.format("%s:%d", host, port);
}
..table.push(headers, ..string.format("Host: %s", hostport));
if(options["origin"]){
..table.push(headers,..string.format("Origin: %s", options["origin"]));
}else{
..table.push(headers,..string.format("Origin: http://%s", hostport));
}
if(options["protocol"]){
..table.push(headers,..string.format("Sec-WebSocket-Protocol: %s", options["protocol"]));
}

var uid = tostring(..win.guid.create().Data1);
var key = ..string.trim(..crypt.bin.encodeBase64(uid));
..table.push(headers, ..string.format("Sec-WebSocket-Key: %s",key), ..string.format("Sec-WebSocket-Version: %s", this.version));
if(options["header"]){
headers = ..table.concat(headers, options["header"]);
}
header_str = ..string.join(headers, '\r\n');
header_str += HEADER_END_SIGN;
this._socket.write(header_str);
if(this.traceEnabled){
..debug.log.print('#Request Header#\n'+header_str);
}
var responseHead = this._socket.readTo(HEADER_END_SIGN);
if(!#responseHead){
this.close();
this.throwerr("Can't connect websocket server");
return;
}
if(this.traceEnabled){
..debug.log.print("#Response Header#\n"+responseHead);
}

var lstHeaders = ..string.list(responseHead,'\r\n', ":");
this.header_protocol = lstHeaders["Sec-WebSocket-Protocol"];
this.header_extensions = lstHeaders["Sec-WebSocket-Extensions"];

if(!validate_header(lstHeaders["Sec-WebSocket-Accept"], key)){
this.close();
this.throwerr("Invalid webSocket header.");
}
};
//Format this object to string(byte array) to send data to server.
this._formatData = function(data = "", opcode){
var fin = 1;
var rsv1 = 0;
var rsv2 = 0;
var rsv3 = 0;
var mask = 1;

var existCode = false;
for(k,v in OPCODES){
if(v === opcode){
existCode = true;
break;
}
}
if(!existCode){
this.throwerr("Invalid opcode.");
}
length = #data;
if(length >= LENGTH_63){
this.throwerr("Data is too long");
}
var frame_header = ..string.pack(fin << 7
| rsv1 << 6 | rsv2 << 5 | rsv3 << 4
| opcode);
if(length < LENGTH_7){
frame_header += ..string.pack(mask << 7 | length)
}elseif(length < LENGTH_16){
frame_header += ..string.pack(mask << 7 | 0x7e)
frame_header += ..string.pack(length);
}else{
frame_header += ..string.pack(mask << 7 | 0x7f)
frame_header += ..string.pack(length);
}
var mask_key = ..math.random(1000, 9999);
return frame_header ++ mask_key ++ this._masked(mask_key, data);
}
//Ping mode
this._ping = function(data){
this.send(data, 9/*_WEBS_OPCODE_PING*/);
};
//Pong mode
this._pong = function(data){
this.send(data, 0xA/*_WEBS_OPCODE_PONG*/);
}
//Listen to receive data
this._listen = function(){
var cont_data = {};

while(true){
//receive frame
var frame_header = this._socket.read(2);
b1 = frame_header[1];
var fin = b1 >> 7 & 1;
var rsv1 = b1 >> 6 & 1;
var rsv2 = b1 >> 5 & 1;
var rsv3 = b1 >> 4 & 1;
var opcode = b1 & 0xf;
b2 = frame_header[2];
var has_mask = b2 >> 7 & 1;
//Frame length
var length_data;
var frame_length = b2 & 0x7f;
if(frame_length == 0x7e){
length_data = this._socket.read(2);
frame_length = ..string.sub(..string.unpack(length_data));
}elseif(frame_length == 0x7f){
length_data = this._socket.read(8);
frame_length = ..string.sub(..string.unpack(length_data));
}
var frame_mask = has_mask ? this._socket.read(4) : "";
var data = this._socket.read(frame_length);
if(has_mask){
data = this._masked(frame_mask, data);
}

if(opcode==1/*_WEBS_OPCODE_TEXT*/ || opcode==2/*_WEBS_OPCODE_BINARY*/ || opcode==0/*_WEBS_OPCODE_CONT*/){
if(cont_data["data"]){
cont_data["data"] += data;
} else{
cont_data["data"] = data;
cont_data["type"] = opcode;
}
if(fin){
if(this.onmessage){
this.onmessage(cont_data);
}
}
}elseif(opcode == 8/*_WEBS_OPCODE_CLOSE*/){
this.send("", 8/*_WEBS_OPCODE_CLOSE*/);
if(this.onmessage){
cont_data["type"] = opcode;
this.onmessage(cont_data);
}
}elseif(opcode == 9/*_WEBS_OPCODE_PING*/){
this._pong(data);
}else {
this.throwerr("Not a valid frame");
}
}
};
//Parse the service url
this.parse_url = function(url){
var parsed = ..inet.url.split(url);
if(!parsed.host || !#parsed.host){
this.throwerr("Host name is invalid");
}
var is_secure = false;
var port = parsed.port;
if(parsed.scheme == "ws"){
port := 80
}elseif(parsed.scheme == "wss"){
is_secure = true
port := 443;
}else{
this.throwerr(..string.format("Invalid scheme:%s", parsed.scheme));
}
var path = parsed.path : "/";
if(parsed.extraInfo){
path += parsed.extraInfo;
}
return ..table.unpack({parsed.host; port; path; is_secure});
};
//Throw error.
this.throwerr = function(msg, code){
if(this.onerror){
var e = {};
e.msg = msg;
e.code = code;
this.onerror(e);
}elseif(this.traceEnabled){
error(msg, 2);
}
}
};
@_metaProperty;
}

namespace socket{
_metaProperty = ..util.metaProperty(
onopen = {
_set = function(value){
if(value){
if(owner.connect_state != 0/*_WEBS_CONNECTING*/ && owner.connect_state != 3/*_WEBS_CLOSED*/){
owner.throwerr("Websocket is opened.")
}
host, port, resource, is_secure = owner.parse_url(owner._url);
owner._socket.connect(host, port);
if(is_secure){
owner.throwerr("SSL not available.");
}
owner._handshake(host, port, resource, owner._options : {});
owner.connect_state = 1/*_WEBS_OPEN*/;
value();
owner._listen();
}
}
};
binaryType = {
_get = function(){
return binary_type;
}
};
readyState = {
_get = function(){
return owner.connect_state;
}
};
bufferedAmount = {
_get = function(){
return owner.buffered_amount;
}
};
extensions = {
_get = function(){
return owner.header_extensions;
}
};
protocol = {
_get = function(){
return owner.header_protocol;
}
};
url = {
_get = function(){
return owner._url;
}
}
close = function(code, reason){
owner.connect_state = 2/*_WEBS_CLOSING*/;
code := 0x3E8/*_WEBS_STATUS_NORMAL*/;
if(code!==1000 || 30004999){
owner.throwerr("Invalid access error");
}
if(owner.onclose){
var arg = {};
arg.code = code;
arg.reason = reason;
if(owner.onclose(arg) === false){
return;
}
}
if(owner.connect_state == 1/*_WEBS_OPEN*/){
owner.send(..string.pack(code) + reason, 8/*_WEBS_OPCODE_CLOSE*/);
}
owner._socket.close();
if(owner.traceEnabled){
..debug.log.print("Disconnect websocket server.");
}
owner.connect_state = 3/*_WEBS_CLOSED*/;
};
send = function(data, datatype){
var buffers = owner._formatData(data, datatype : 1/*_WEBS_OPCODE_TEXT*/);
length = #buffers;
owner._socket.write(buffers, buffered_amount);
if(owner.traceEnabled){
..debug.log.print(..string.format("Complete send data:%s",data));
}
return length;
}
);
}
}


/**intellisense(web)
socket('__/*url*/', /*选项(可选)*/) = 构造WebSocket客户端对象\n!client
!client.readyState = 当前连接状态(只读)
!client.protocol = 服务器所选中的协议(只读)
!client.extensions = 服务器所选中的扩展名(只读)
!client.url = 套接字的当前 URL(只读)
!client.onopen = @.onopen = function(){
__/*打开并连接websocket服务器*/
}
!client.onmessage = @.onmessage = function(e){
__/*接受服务端消息*/
}
!client.onerror = @.onerror = function(e){
__/*错误捕获*/
}
!client.onclose = @.onclose = function(e){
__/*关闭websocket连接,返回false阻止关闭*/
}
!client.send(data, datatype) = 发送数据
!client.close(code, reason) = 断开并关闭连接
end intellisense**/


/**intellisense()
_WEBS_CONNECTING=@0/*_WEBS_CONNECTING*/
_WEBS_OPEN=@1/*_WEBS_OPEN*/
_WEBS_CLOSING=@2/*_WEBS_CLOSING*/
_WEBS_CLOSED=@3/*_WEBS_CLOSED*/
_WEBS_OPCODE_CONT=@0/*_WEBS_OPCODE_CONT*/
_WEBS_OPCODE_TEXT=@1/*_WEBS_OPCODE_TEXT*/
_WEBS_OPCODE_BINARY=@2/*_WEBS_OPCODE_BINARY*/
_WEBS_OPCODE_CLOSE=@8/*_WEBS_OPCODE_CLOSE*/
_WEBS_OPCODE_PING=@9/*_WEBS_OPCODE_PING*/
_WEBS_OPCODE_PONG=@0xA/*_WEBS_OPCODE_PONG*/
_WEBS_BINARYTYPE_BLOB=@1/*_WEBS_BINARYTYPE_BLOB*/
_WEBS_BINARYTYPE_ARRAYBUFFER=@2/*_WEBS_BINARYTYPE_ARRAYBUFFER*/
_WEBS_STATUS_NORMAL=@0x3E8/*_WEBS_STATUS_NORMAL*/
_WEBS_STATUS_GOING_AWAY=@0x3E9/*_WEBS_STATUS_GOING_AWAY*/
_WEBS_STATUS_PROTOCOL_ERROR=@0x3EA/*_WEBS_STATUS_PROTOCOL_ERROR*/
_WEBS_STATUS_UNSUPPORTED_DATA_TYPE=@0x3EB/*_WEBS_STATUS_UNSUPPORTED_DATA_TYPE*/
_WEBS_STATUS_STATUS_NOT_AVAILABLE=@0x3ED/*_WEBS_STATUS_STATUS_NOT_AVAILABLE*/
_WEBS_STATUS_ABNORMAL_CLOSED=@0x3EE/*_WEBS_STATUS_ABNORMAL_CLOSED*/
_WEBS_STATUS_INVALID_PAYLOAD=@0x3EF/*_WEBS_STATUS_INVALID_PAYLOAD*/
_WEBS_STATUS_POLICY_VIOLATION=@0x3F0/*_WEBS_STATUS_POLICY_VIOLATION*/
_WEBS_STATUS_MESSAGE_TOO_BIG=@0x3F1/*_WEBS_STATUS_MESSAGE_TOO_BIG*/
_WEBS_STATUS_INVALID_EXTENSION=@0x3F2/*_WEBS_STATUS_INVALID_EXTENSION*/
_WEBS_STATUS_UNEXPECTED_CONDITION=@0x3F3/*_WEBS_STATUS_UNEXPECTED_CONDITION*/
_WEBS_STATUS_TLS_HANDSHAKE_ERROR=@0x3F7/*_WEBS_STATUS_TLS_HANDSHAKE_ERROR*/
end intellisense**/

图片名称
求大佬解释,或者有没有更完善的库,谢谢~
  • wwsheng wwsheng    被采纳
    Time:2017-06-15 11:27:01
    hp socket库自带websocket功能。安装websocket库后,可以查看自带的示例库。
    server:
    import win.ui;
    /*DSG{{*/
    mainForm = win.form(text="WebSocket服务器";right=759;bottom=469)
    mainForm.add(
    edit={cls="edit";left=18;top=19;right=739;bottom=444;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=1}
    )
    /*}}*/

    import hpsocket.httpServer;
    var hpHttpServer = hpsocket.httpServer();

    mainForm.edit.threadCallable();
    hpHttpServer.threadGlobal = {
    mainForm = mainForm;
    }

    //监听线程被创建后触发
    hpHttpServer.onThreadCreated = function(){}

    //监听线程退出前触发此事件
    hpHttpServer.onThreadEnd = function(){}

    //允许升级为WebSocket协议
    hpHttpServer.onUpgrade = function(hpHttpServer,connId,upgradeType){

    if(upgradeType!=1) return -1;
    hpHttpServer.sendWsSwitchingProtocols(connId);
    }


    hpHttpServer.onWsMessageHeader = function(hpHttpServer,connId,final,reserved,opCode,mask,bodyLen){
    /*
    final:是否结束帧
    opCode:
    0:标识一个中间数据包
    1:标识一个text类型数据包,UTF8编码
    2:标识一个binary类型数据包
    8:标识一个断开连接类型数据包
    9:标识一个ping类型数据包
    10:表示一个pong类型数据包
    bodyLen:数据长度

    其他参数不用理会
    */
    hpHttpServer.reallocString(connId,bodyLen);//初始化缓冲区
    }

    //接收到WebSocket请求数据
    hpHttpServer.onWsMessageBody = function(hpHttpServer,connId,pData,len){
    hpHttpServer.appendString(connId,pData,len);
    }

    //WebSocket请求数据接收完成
    hpHttpServer.onWsMessageComplete = function(hpHttpServer,connId){

    var data = hpHttpServer.getString(connId);
    if( data ){
    //向客户端发送数据
    hpHttpServer.sendWsMessage(connId,"我是服务端,收到了你的:"+data);
    mainForm.edit.printf("收到客户端消息:%s",data)
    }
    }

    hpHttpServer.onClose = function(hpHttpServer,connId,enOperation,errCode){
    hpHttpServer.reallocString(connId,0);//释放缓冲区
    }

    hpHttpServer.start(/*IP*/,7511)
    mainForm.edit.printf("已启动:%s",hpHttpServer.getWsUrl() )

    mainForm.onClose = function(hwnd,message,wParam,lParam){
    hpHttpServer.stop();
    }

    mainForm.show()
    win.loopMessage();

    client:
    import win.ui;
    /*DSG{{*/
    mainForm = win.form(text="WebSocket服务器";right=759;bottom=469)
    mainForm.add(
    edit={cls="edit";left=18;top=19;right=739;bottom=444;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=1}
    )
    /*}}*/

    import hpsocket.httpClient;
    var hpHttpClient = hpsocket.httpClient();

    mainForm.edit.threadCallable();
    hpHttpClient.threadGlobal = {
    mainForm = mainForm;
    }

    //监听线程被创建后触发
    hpHttpClient.onThreadCreated = function(){}

    //监听线程退出前触发此事件
    hpHttpClient.onThreadEnd = function(){}

    //允许升级为WebSocket协议
    hpHttpClient.onUpgrade = function(hpHttpClient,connId,upgradeType){
    if(upgradeType!=1) return -1;

    if( ! hpHttpClient.checkWsUpgradeResponse() )
    return -1;//验证密钥错误

    //升级协议成功,向服务端发送消息试试
    hpHttpClient.sendWsMessage("我是客户端,早上好呀");
    }

    //接收到WebSocket请求头
    hpHttpClient.onWsMessageHeader = function(hpHttpClient,connId,final,reserved,opCode,mask,bodyLen){
    hpHttpClient.reallocString(bodyLen);//初始化缓冲区
    }

    //接收到WebSocket请求数据
    hpHttpClient.onWsMessageBody = function(hpHttpClient,connId,pData,len){
    hpHttpClient.appendString(pData,len);
    }

    //WebSocket请求数据接收完成
    hpHttpClient.onWsMessageComplete = function(hpHttpClient){
    var data = hpHttpClient.getString();
    if( data ){
    mainForm.edit.printf("收到服务端消息:%s",data)
    }
    }

    hpHttpClient.onConnect = function(hpHttpClient){
    hpHttpClient.sendWsUpgradeRequest("/");
    }

    hpHttpClient.onClose = function(hpHttpClient,connId,enOperation,errCode){
    hpHttpClient.reallocString(0);
    }

    hpHttpClient.start("localhost",7511);
    mainForm.onClose = function(hwnd,message,wParam,lParam){
    hpHttpClient.stop();
    }

    mainForm.show()
    win.loopMessage();

  • Admin Admin    
    Time:2017-06-15 12:10:57
    楼上正解。请在aardio右侧的工具面板顶部打到“扩展库”,双击运行,勾上hpsocket安装即可。
[ 发单/接单 ]
换IP投票软件
PC蛋蛋自动挂机投注
新浪微博发微博显示尾巴的方法,比如显示来自iphone 7
百度文库批量自动上传软件
一点资讯app刷阅读量/评论/收藏/订阅功能/手机号注册
定做一个阿迪达斯官网注册器(需要破点击文字式验证码)
定制人人网自动注册/修改资料/采集/私聊软件
酷狗繁星直播网页协yi
YY多功能刷订阅刷粉丝
滑块验证码本地识别
狼人杀POST QQ登录注册 获取金币数量
做个贴吧发发帖的软件懂的来
今日头条账号保存cookie
抖音粉丝软件定做,只要粉丝
百家号自媒体发文软件定制
哔哩哔哩播放量
读取TB某个商品上架时间和相关信息
网易博客软件定制
定制天涯论坛发帖软件
定制今日头条批量自动发私信软件
[ 站内搜索 ]
[ 最近热帖 ]
万能助手 -- 扩展库大全集 13745
用aardio创建web工程图文讲解(1) 12831
电脑编程入门自学:Fiddler https 抓包时提示创建根证书不成功问题彻底解决(https插件dll方式) 11737
aardio绘图演示 11407
通过chrome.dll中间件控制外部chrome浏览器 10117
我常用的aardio技巧 9768
《边学C语言边赚钱——简码编程入门教程》系列集合 9612
aardio使用http或whttp进行get/post请求时经常cookies失效怎么办?__电脑计算机编程入门教程自学 9318
[源码下载]简码视频加密解密播放工具个人版v1.0发布,永久免费开源的知识变现神器 8554
python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学 8046
编程入门教程:aardio批量上传文件并显示进度条 7878
aardio调用nodejs的ws模块做一个简单的聊天通信示例 7034
电脑计算机编程入门教程自学:原生JavaScript判断字符是否为A-Za-z英文字母 6904
电脑计算机编程入门教程自学:腾讯tx或极验geetest滑块按住拖动完成拼图验证成功破解思路及源码 6498
乐玩插件AARDIO调用 6081
[ 近期热答 ]
电脑计算机编程入门教程自学:什么是buffer缓冲区? 1
aardio_代码编辑框书签管理器开源 1
aardio_怎么用ide库从代码编辑框中取出指定行的源码? 1
aardio_codepage代码页编码乱码暴力猜解工具 1
aardio内嵌echarts图表添加鼠标事件响应功能 2
aardio列表框listbox_模糊查找和精确查找 1
8亿QQ绑定手机泄露:通过腾讯QQ号查询QQ绑定的手机号码漏洞! 1
carl listviewex调用例子----------源码搬运工 2
Aardio内嵌Electron浏览框怎么正确添加启动参数? 1
Aardio取汉字的字节数或字符数 1
怎么实现mssql图片数据的读写 2
aardio_从49个数字里选六个和值为150的不重复的数字 1
在嵌入wps的时候,多了一个 透明的边框,这个怎么消除它 1
万能助手入门帮助教程:学会科学地管理工作文件 1
Aaardio开发内嵌Electron浏览框放服务器上无法下载组件的解决办法 1