采用自定义协议代替OCX组件
事情起源:公司视频播放一直是采用的嵌入浏览器组件实现视频的预览回放等功能。这种实现方式要求客户使用IE浏览器。
最近上线项目使用Html 5开发,要求IE11。项目中使用了视频播放功能,如果全部升级到IE11问题多,工作量大。
存在的主要问题:
有些系统开发较早,不能在IE11上运行。
部分客户电脑配置低还在使用XP。因为视频播放插件要求IE浏览器,所以支持H5的chrome,firefox等浏览器又不符合要求。
修改项目兼容低版本浏览器那是不可能的,只能修改视频播放插件。
1、视频插件改为 应用程序 安装到客户计算机,使用浏览器自定义协议启动。这样解决了浏览器兼容问题,几乎所有浏览器都支持自定义协议。
测试用例:注册表写入以下内容就可以启动 d:\myapp.exe
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\myapp]
@="URL:AutoHotKey myapp Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\myapp\DefaultIcon]
@="myapp.exe,1"
[HKEY_CLASSES_ROOT\myapp\shell]
[HKEY_CLASSES_ROOT\myapp\shell\open]
[HKEY_CLASSES_ROOT\myapp\shell\open\command]
@="\"d:\\myapp.exe\" \"%1\""
javascript 点击启动myapp.exe
function LaunchApp() {
try {
window.location = 'myapp://,start';
}
catch (ex) {
errMsg = "启动 myapp 报错.\n\n";
alert(errMsg);
}
return;
};
2、如何判断用户有没安装视频应用呢??
网上搜索了一下,看着比较靠谱的:
https://www.cnblogs.com/tangjiao/p/9646855.html
这个实现方案是有缺陷,在chrome浏览器通过计时器和当前窗体失去焦点来判段。
计时器设置时间短路了,程序在配置低的电脑上会失败。
计时器设置时间长了,chrome上切换tab页就失去焦点,认为已经安装。
通过观察百度云盘的运行方式,得到启发。百度云盘也是采用了自定义协议。启动yundetectservice.exe 监听10000端口,
猜测web页面和yundetectservice.exe进行了通信。yundetectservice.exe启动成功会通知web页面。
3、采用 websocket 实现,视频应用启动的时候监听某端口等待 web页面连接,如果一定时间内连接成功就认为已经安装了插件。
web页面websocket连接的例子网上比较多。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
var noSupportMessage = "Your browser cannot support WebSocket!";
var ws; function appendMessage(message) {
$('body').append(message);
} function connectSocketServer() {
var support = "MozWebSocket" in window ? 'MozWebSocket' : ("WebSocket" in window ? 'WebSocket' : null); if (support == null) {
appendMessage("* " + noSupportMessage + "<br/>");
return;
} appendMessage("* Connecting to server ..<br/>");
// create a new websocket and connect
ws = new window[support]('ws://localhost:12345/'); // when data is comming from the server, this metod is called
ws.onmessage = function (evt) {
appendMessage("# " + evt.data + "<br />");
}; // when the connection is established, this method is called
ws.onopen = function () {
appendMessage('* Connection open<br/>');
$('#messageInput').attr("disabled", "");
$('#sendButton').attr("disabled", "");
$('#connectButton').attr("disabled", "disabled");
$('#disconnectButton').attr("disabled", "");
}; // when the connection is closed, this method is called
ws.onclose = function () {
appendMessage('* Connection closed<br/>');
$('#messageInput').attr("disabled", "disabled");
$('#sendButton').attr("disabled", "disabled");
$('#connectButton').attr("disabled", "");
$('#disconnectButton').attr("disabled", "disabled");
}
} function sendMessage() {
if (ws) {
var messageBox = document.getElementById('messageInput');
ws.send(messageBox.value);
messageBox.value = "";
}
} function disconnectWebSocket() {
if (ws) {
ws.close();
}
} function connectWebSocket() {
connectSocketServer();
} window.onload = function () {
$('#messageInput').attr("disabled", "disabled");
$('#sendButton').attr("disabled", "disabled");
$('#disconnectButton').attr("disabled", "disabled");
} </script>
</head>
<body>
<input type="button" id="connectButton" value="Connect" onclick="connectWebSocket()"/> <input type="button" id="disconnectButton" value="Disconnect" onclick="disconnectWebSocket()"/> <input type="text" id="messageInput" /> <input type="button" id="sendButton" value="Send" onclick="sendMessage()"/> <br />
</body>
</html>
实现websocket服务也有很多方法。
开源的有,SuperWebSocket,Fleck,WebSocketListener,websocket-sharp 等。
DotNet 高版本自带了System.Net.WebSockets;
因为功能简单,仅仅是接受连接请求,所以采用dontnet自带的,不用引入多余的类库。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace TestServer
{
class Program
{
static void Main(string[] args)
{
RunEchoServer().Wait();
}
private static async Task RunEchoServer()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:12345/");
listener.Start();
Console.WriteLine("Started");
while (true)
{
HttpListenerContext context = listener.GetContext();
//
if (!context.Request.IsWebSocketRequest)
{
context.Response.Close();
continue;
}
//
Console.WriteLine("Accepted");
//
var wsContext = await context.AcceptWebSocketAsync(null);
var webSocket = wsContext.WebSocket;
//
byte[] buffer = new byte[];
WebSocketReceiveResult received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); while (received.MessageType != WebSocketMessageType.Close)
{ Console.WriteLine($"Echoing {received.Count} bytes received in a {received.MessageType} message; Fin={received.EndOfMessage}");
// Echo anything we receive
await webSocket.SendAsync(new ArraySegment<byte>(buffer, , received.Count), received.MessageType, received.EndOfMessage, CancellationToken.None); received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
} await webSocket.CloseAsync(received.CloseStatus.Value, received.CloseStatusDescription, CancellationToken.None); webSocket.Dispose();
Console.WriteLine("Finished");
}
}
}
}
至此,通过自定义协议和websocket 解决了视频插件的问题。
采用自定义协议代替OCX组件的更多相关文章
- OCX组件
转自:http://blog.sina.com.cn/s/blog_4ca9ceef0100ixzb.html 一.OCX(OLE Control Extensio,OLE Object Linkin ...
- 利用Netty构建自定义协议的通信
在复杂的网络世界中,各种应用之间通信需要依赖各种各样的协议,比如:HTTP,Telnet,FTP,SMTP等等. 在开发过程中,有时候我们需要构建一些适应自己业务的应用层协议,Netty作为一个非常优 ...
- C#综合揭秘——通过修改注册表建立Windows自定义协议
引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对 ...
- java-cef系列视频第四集:自定义协议
上一集我们介绍了如何为java-cef添加flashplayer支持. 本视频介绍java-cef中的自定义协议 本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 中国大陆许可协议进行许可.
- 在网络7层协议中,如果想使用UDP协议达到TCP协议的效果,可以在哪层做文章?(QQ 为什么采用 UDP 协议,而不采用 TCP 协议实现?)
为了解决这题,可以具体看看下面这个讨论. 解灵运工程师 185 人赞同 某次架构师大会上那个58同城做即时通信的人说:原因是因为当时没有epoll这种可以支持成千上万tcp并发连接的技术,所以他们使用 ...
- 【转】C#综合揭秘——通过修改注册表建立Windows自定义协议
引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对 ...
- 各种非标232,485协议,自定义协议转modbus协议模块定制开发,各种流量计协议转modbus,
工业现场经常会碰到通过485或者232采集各类仪表数据,但是很多早期的仪表和设备不支持标准modbus协议,而是采用自定义的协议,这些协议数据由plc或者dcs系统来实现采集,不仅费时麻烦,而且不方便 ...
- 移动网络应用开发中,使用 HTTP 协议比起使用 socket 实现基于 TCP 的自定义协议有哪些优势?
HTTP 是应用层协议,TCP 是传输层协议(位于应用层之下),放在一起类比并不合适.不过猜测楼主是想对比 “标准 HTTP 协议” 还是 “自定义的协议(基于 TCP Socket)” . 一般来说 ...
- 通过修改注册表建立Windows自定义协议
引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对 ...
随机推荐
- 前端开发:一个开源、简单易用的jQuery表格插件(DataTables)
DataTables是一个基于jQuery库的开源(MIT协议)表格插件,支持添加.排序.分页.搜索.过滤等功能,使用简单.广受欢迎,能够与主流前端UI整合(如bootstrap.jQuery UI等 ...
- SQL性能优化十条经验,后台程序员都需要掌握
1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE '%parm1%'—— 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用. 解决办法: 其实只需要对该脚本略做改进,查询速度便会 ...
- 1040 mysql Too many connections
笔者在项目中遇到mysql 出现:1040 too many connections 异常,意思是超过数据库最大连接数,打不开表结构信息.笔者排除问题建议:1.查看程序代码是否存在BUG:2.检查代码 ...
- MYSQL常用命令2
mysql 的dos命令行大全 2016年11月04日 16:03:59 阅读数:7987 1.连接Mysql(中文乱码在文章的最后) 格式: mysql -h主机地址 -u用户名 -p用户密码 1. ...
- 小程序开发:canvas在画布上滑动,页面跟着滑动问题
微信小程序官方文档有说明,disable-scroll="true" 可以阻止页面下拉和滚动.这里有个坑,disable-scroll在真机上如果要生效,那么要给canvas绑定一 ...
- 爬虫模块介绍--Beautifulsoup (解析库模块,正则)
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...
- inno安装客户端,写注册表url调用客户端
[Registry] Root: HKCR; SubKey: xxx; ValueData: "xxx"; ValueType: string; Flags: CreateValu ...
- 学习笔记TF062:TensorFlow线性代数编译框架XLA
XLA(Accelerated Linear Algebra),线性代数领域专用编译器(demain-specific compiler),优化TensorFlow计算.即时(just-in-time ...
- Viewport模版
通用模版 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta ...
- Hot Chocolate 一个.net 平台的graphql 框架
在看昨天发布的新版技术雷达中,看到了一个.net 的graphql 框架Hot Chocolate 还是比较激动,尽管好久不搞 .net 了,但是这个框架还是值得看看的,后边学习下 参考资料 http ...