经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
采用自定义协议代替OCX组件
来源:cnblogs  作者:OneCool  时间:2018/12/3 10:18:02  对本文有异议

事情起源:公司视频播放一直是采用的嵌入浏览器组件实现视频的预览回放等功能。这种实现方式要求客户使用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连接的例子网上比较多。

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <html>
  3. <head>
  4. <title>Test</title>
  5. <script type="text/javascript" src="jquery.js"></script>
  6. <script type="text/javascript">
  7. var noSupportMessage = "Your browser cannot support WebSocket!";
  8. var ws;
  9. function appendMessage(message) {
  10. $('body').append(message);
  11. }
  12. function connectSocketServer() {
  13. var support = "MozWebSocket" in window ? 'MozWebSocket' : ("WebSocket" in window ? 'WebSocket' : null);
  14. if (support == null) {
  15. appendMessage("* " + noSupportMessage + "<br/>");
  16. return;
  17. }
  18. appendMessage("* Connecting to server ..<br/>");
  19. // create a new websocket and connect
  20. ws = new window[support]('ws://localhost:12345/');
  21. // when data is comming from the server, this metod is called
  22. ws.onmessage = function (evt) {
  23. appendMessage("# " + evt.data + "<br />");
  24. };
  25. // when the connection is established, this method is called
  26. ws.onopen = function () {
  27. appendMessage('* Connection open<br/>');
  28. $('#messageInput').attr("disabled", "");
  29. $('#sendButton').attr("disabled", "");
  30. $('#connectButton').attr("disabled", "disabled");
  31. $('#disconnectButton').attr("disabled", "");
  32. };
  33. // when the connection is closed, this method is called
  34. ws.onclose = function () {
  35. appendMessage('* Connection closed<br/>');
  36. $('#messageInput').attr("disabled", "disabled");
  37. $('#sendButton').attr("disabled", "disabled");
  38. $('#connectButton').attr("disabled", "");
  39. $('#disconnectButton').attr("disabled", "disabled");
  40. }
  41. }
  42. function sendMessage() {
  43. if (ws) {
  44. var messageBox = document.getElementById('messageInput');
  45. ws.send(messageBox.value);
  46. messageBox.value = "";
  47. }
  48. }
  49. function disconnectWebSocket() {
  50. if (ws) {
  51. ws.close();
  52. }
  53. }
  54. function connectWebSocket() {
  55. connectSocketServer();
  56. }
  57. window.onload = function () {
  58. $('#messageInput').attr("disabled", "disabled");
  59. $('#sendButton').attr("disabled", "disabled");
  60. $('#disconnectButton').attr("disabled", "disabled");
  61. }
  62. </script>
  63. </head>
  64. <body>
  65. <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 />
  66. </body>
  67. </html>

 

实现websocket服务也有很多方法。

开源的有,SuperWebSocket,Fleck,WebSocketListener,websocket-sharp 等。

DotNet 高版本自带了System.Net.WebSockets;

因为功能简单,仅仅是接受连接请求,所以采用dontnet自带的,不用引入多余的类库。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.WebSockets;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace TestServer
  10. {
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. RunEchoServer().Wait();
  16. }
  17. private static async Task RunEchoServer()
  18. {
  19. HttpListener listener = new HttpListener();
  20. listener.Prefixes.Add("http://localhost:12345/");
  21. listener.Start();
  22. Console.WriteLine("Started");
  23. while (true)
  24. {
  25. HttpListenerContext context = listener.GetContext();
  26. //
  27. if (!context.Request.IsWebSocketRequest)
  28. {
  29. context.Response.Close();
  30. continue;
  31. }
  32. //
  33. Console.WriteLine("Accepted");
  34. //
  35. var wsContext = await context.AcceptWebSocketAsync(null);
  36. var webSocket = wsContext.WebSocket;
  37. //
  38. byte[] buffer = new byte[1024];
  39. WebSocketReceiveResult received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
  40. while (received.MessageType != WebSocketMessageType.Close)
  41. {
  42. Console.WriteLine($"Echoing {received.Count} bytes received in a {received.MessageType} message; Fin={received.EndOfMessage}");
  43. // Echo anything we receive
  44. await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, received.Count), received.MessageType, received.EndOfMessage, CancellationToken.None);
  45. received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
  46. }
  47. await webSocket.CloseAsync(received.CloseStatus.Value, received.CloseStatusDescription, CancellationToken.None);
  48. webSocket.Dispose();
  49. Console.WriteLine("Finished");
  50. }
  51. }
  52. }
  53. }

 

至此,通过自定义协议和websocket 解决了视频插件的问题。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号