WebSocket
概述
VDN 提供了对 WebSocket 的支持,通过 WebSocket 不但可以实现不同程序之间的消息通讯,还可以通过 WebAPI 调用 VDN 的插件函数.
WebSocket 使用了同 VDN WebAPI相同的协议,都是基于 JSON-RPC 协议格式;阅读本章节之前请先阅读【WebAPI】了解相关内容,至少先阅读【协议描述】了解 VDN 所使用协议的基本格式。
安全保障
VDN 为 WebSocket 提供了多重安全保障:
访问级别
登录 WebSocket 时根据系统选项【验证令牌】,将进行令牌检查验证,令牌使用方式参加【WebSocket 携带令牌】.
调用 WebAPI 时由提供服务的 PB 插件决定了访问级别,针对 WebSocket 分为【匿名访问】和【令牌访问】两种安全级别,详见:【项目发布】-【身份验证】
【匿名访问】对外部访问不设置限制,可以任意访问
【令牌访问】必须通过约定的规则获取令牌后才可以进行访问, 适用于外部域进行访问,安全性高,详见:如何获取令牌
来源验证
通过设置【验证来源】选项,VDN 会对外部访问的来源都进行验证,只有属于预先设定的来源路径才可以访问,杜绝非法的访问。来源设定详见:外部来源
自定义验证
用户可以在插件代码中增加自定义验证,设定握手协议,只有满足条件的调用才给予正确的返回值.
WebSocket 设置

【系统设置】-【Web】-【Web 设置】-【WebSocket】关于 WebSocket 的选项
WS 路径:定义访问 WebSocket 的子路径,默认
ws。可以定义为任意不重复的英文名称,例如定义为 abc,则访问 WebSocket 的 URL 路径就为:ws://www.xxx.com:8088/abc外部登录:是否允许除了 VDN 客户端外的其他开发语言或系统登录 WebSocket,只有选中此选项才可以通过 JS 脚本的方式登录到 WebSocket
跨域访问:是否允许外部站点、程序跨域访问 WebSocket,如果不选择则只允许本站点的页面访问 WebSocket,外部将无法访问。
验证来源:当访问来源为外部时,判断来源地址是否属于在【外部来源】中设置的地址列表,如果不属于则拒绝访问。
验证令牌:登录 WebSocket 时是否检查其携带的令牌是否有效
消息登录
登录参数
ws.send('{"id":"login","method":"online","params":{"Group":"通用","Soft":"App","UserID":"1","UserName":"小明","MsgFormat":"json","Online":"^self","GetMsg","1""GetOnlineMsg":"1","GetSimpleOnlne":"1"}}');
//或
ws.send('{"id":"login","method":"online","params":{"Group":"通用","Soft":"App","UserID":"1","UserName":"小明","MsgFormat":"json");
//或
ws.send('{"id":"login","method":"online","params":{"Group":"通用","UserID":"1","UserName":"小明"}}');id
login 标识为登录操作,在判断返回值时会用到.这里也可以自定义为其他值。
method
online 告知服务器进行 online 操作
params
同【消息登录相关属性】一一对应,包含如下属性:
| 参数 | 必须 | 说明 | 举例 |
|---|---|---|---|
| Group | 必须 | 指定登录后的用户组 | "Group":"通用" |
| UserID | 必须 | 用户 ID | "UserID":"9999" |
| UserName | 必须 | 用户名 | "UserName":"小明" |
| Soft | 软件名称,对应在线列表中的[系统]一栏 默认:Other | "Soft":"App" | |
| MsgFormat | 接收消息的格式 | "MsgFormat":"json" | |
| Online | 获取服务器在线的用户列表及上线消息的过滤条件 默认 ^self 详情参见:【消息推送-onlineFilter】属性说明 | "Online":"online/通用" | |
| GetMsg | 是否接收服务器推送的消息; 登录只为完成其他的一些操作,可以设置不接收消息推送 | "GetMsg":"0" | |
| GetOnlineMsg | 是否获取用户上/下线消息通知 | "GetOnlineMsg":"1" | |
| GetSimpleOnlne | 是否只获取简短的在线用户信息 简短信息不包含 IP、上线时间、状态等 | "GetSimpleOnlne":"0" |
登录
ws = new WebSocket(serverURL);
//open之后立即发送登录消息
ws.onopen = function (e) {
ws.send('{"id":"login","method":"online","params":{"Group":"通用","Soft":"App","UserID":"8888","UserName":"小明","MsgFormat":"json","Online":"^self","GetOnlineMsg":"1","GetSimpleOnlne":"1"}}');
};发送消息登录应该在 WebSocket 的 open 事件中,当连接建立就立即发送;
登录返回值:
登录成功后服务器端会返回 ResponseID,这个 ID 是客户端在服务器端独立唯一的标识。
返回的信息格式根据 MsgFormat 的值决定:
{
"ID": "login",
"Error": null,
"Result": { "ResponseID": "C3272FE12957DE4641CCE179789E6E38" }
}消息接收
消息接收在 WebSocket 对象的 message 事件中执行
//消息到达
ws.onmessage = function (e) {
try {
//构建
var obj = JSON.parse(event.data);
//核心内容
$("#t_return").text(JSON.stringify(obj.Result));
if (obj.Error == null) {
//分析 obj.ID 对应Send数据是的JSON的ID
switch (obj.ID) {
case "login":
$("<li>")
.text("登录成功,ResponseID:" + obj.Result.ResponseID)
.appendTo($ul);
break;
case "online":
var user = obj.Result;
$("<li>")
.text(user.UserName + "登录")
.appendTo($ul);
break;
case "outline":
var user = obj.Result;
$("<li>")
.text(user.ID + "注销")
.appendTo($ul);
break;
case "msg":
var msg = obj.Result;
$("<li>")
.text(msg.FromUserID + "说:" + msg.Msg)
.appendTo($ul);
break;
case "send": //消息发送成功返回
var msg = obj.Result;
$("<li>")
.text("消息成功发送给 " + msg.succeed + " 个人")
.appendTo($ul);
break;
case "GetData": //获取数据
//parse table
$.jsontotable(JSON.parse(obj.Result).rows, {
id: "#jsontotable-obj",
});
break;
default:
$("<li>")
.text("Other Type:" + obj.ID)
.appendTo($ul);
}
} else {
//Error 系统返回错误信息
alert(obj.Error.Message + "(" + obj.Error.Code.toString() + ")");
}
} catch (e) {
$("<li>").text(event.data).appendTo($ul);
alert(e.name + ":" + e.message + " code:" + e.number);
}
};如果设定以文本格式返回,则消息通讯返回的格式是:
消息类型(MsgType)/消息主体/发送者 ID/发送者 ResponseID
文本格式如果是其他操作则格式各有不同,比如调用 WebAPI,则由接口执行的返回格式决定
msg/hello/8888/A2758C412650277629F3BA5C41DB3DE3推荐使用 JSON 格式,消息的可读性更强一些
{
"ID": "msg",
"Error": null,
"Result": {
"FromResponseID": "A2758C412650277629F3BA5C41DB3DE3",
"FromUserID": "8888",
"Msg": "hello"
}
}注意
这里的 ID 是与发送消息时的 ID 相同的,比如发送的 ID 为 abc,则返回的 ID 也为 abc.
接收其他用户发送的消息时的 ID 等于发送者发送的 MsgType.
ID 值有几个系统保留的如下:
| ID | 说明 |
|---|---|
| online | 用户的上线通知 |
| outline | 用户的下线通知 |
调用 WebAPI
WebSocket 调用 WebAPI 的数据格式同 Ajax 调用 API 的格式,只是仅支持发送 JSON 格式.详情请参见WebAPI 章节
var data = {
ID: "GetData",
method: "[PBPlugin].f_getdata",
Params: ["a1", "a2"],
};
var jsonStr = JSON.stringify(data);
ws.send(jsonStr);在 WebSocket 组件登录后即可通过 send 函数调用 WebAPI,返回值在 messge 事件中处理

这里的 ID 同 send 函数发送的 ID:"GetData"是对应的,同样支持自定义.
示例代码
示例代码位置:Example\Web功能\WebAPI\ 目录下
示例代码主要使用了 JQuery 的 WebSocket 对象进行了访问演示,JSON 解析为 Table 表格使用了 jquery.jsontotable.min 插件,均为演示需要,实际使用可以任意不受限制。
