前一段时间有个朋友要帮忙做一个在web端调用硬件的sdk。沟通后才知道是买的供应商的一套视频设备。由于视频设备的软件和sdk只有c++版的,于是给他们中间做了一层c# 封装。技术方案呢开始时想用ocx 插件来做。后来觉得后期给客户安装比较麻烦,后面改成了websocket 来做。
websocket c#端采用 Fleck 来接收和发送报文。
工程类型可以采用winform 、控制台或者window服务都可以
我这里就用winform 做个介绍
首先创建一个winform 工程解决方案
NuGet程序包管理器下载Fleck即可
由于要用到转json所以也下了Newtonsoft.Json
c# 端实现的是一个 调用c++的接口函数 拍照。拍照固定保存到电脑硬盘地址。调用完成之后c# 返回文件地址给到前端去显示。
调用c++接口函数
private const string dllPath = @"WinDLL.dll";
[DllImport(dllPath, EntryPoint = "DrawGraph", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern int DrawGraph(int width, int height, IntPtr mhwnd);
websocket 端口号可以自己定,我这里是8181
WebSocketServer server = new WebSocketServer("ws://0.0.0.0:8181");
接下来在构造函数里开启socket服务
StartWebSocket();
Socket 接收到消息后解析数据,根据数据命令判断执行接口,这里是调用c++拍照后画图显示。图像保存到本地后回传给网页端。当然这里也可以上传到云端服务器都可以。
server.Start(socket =>
{
socket.OnOpen = () =>
{
JObject cntObject = new JObject { { "res", "" } };
ResultApi resultApi = new ResultApi { result = cntObject };
resultApi.message = resultApi.status == 0 ? "返回成功" : "返回错误";
resultApi.result = "Open Sucess";
string jResult = JsonConvert.SerializeObject(resultApi);
socket.Send(jResult);
Console.WriteLine(jResult);
};
socket.OnClose = () => {
JObject cntObject = new JObject { { "res", "" } };
ResultApi resultApi = new ResultApi { result = cntObject };
resultApi.message = resultApi.status == 0 ? "返回成功" : "返回错误";
resultApi.result = "Close Sucess";
string jResult = JsonConvert.SerializeObject(resultApi);
socket.Send(jResult);
Console.WriteLine(jResult);
};
socket.OnMessage = message =>
{
Console.WriteLine(message);
try
{
string jResult = null;
var param = JsonConvert.DeserializeObject<RequestParam>(message);
if (param.FuncName == "DrawGraph")
{
this.Invoke(new Action(() =>
{
var hdc = pb_Img.Handle;
var resStr = DrawGraph( pb_Img.Width, pb_Img.Height, hdc);
ResultApi resultApi = new ResultApi { status = resStr};
resultApi.message = resultApi.status == 1 ? "返回成功" : "返回错误";
var name = DateTime.Now.ToString("yyyyMMddHHmmss");
resultApi.message = name;
Bitmap bit = new Bitmap(pb_Img.Width, pb_Img.Height);
pb_Img.DrawToBitmap(bit, pb_Img.ClientRectangle);
bit.Save($@"{name}.jpg", System.Drawing.Imaging.ImageFormat.Bmp);
jResult = JsonConvert.SerializeObject(resultApi);
}));
Console.WriteLine(jResult);
socket.Send(jResult);
}
}
catch (Exception ex)
{
ResultApi resultApi = new ResultApi();
resultApi.status = 1;
resultApi.message = "返回失败 参数不对";
var errorres = JsonConvert.SerializeObject(resultApi);
Console.WriteLine(errorres);
socket.Send(errorres);
}
};
});
web端 用html 页面来做验证
js代码
<script type="text/javascript">
var socket;
if ("WebSocket" in window) {
var ws = new WebSocket("ws://localhost:8181/echo");
socket = ws;
ws.onopen = function () {
ws.send("Message from client");
console.log('Message is sent...');
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
var json = JSON.parse(received_msg);
document.getElementById('img').src = json.message + ".jpg";
console.log("Server:" + evt.data);
};
ws.onclose = function () {
alert("Connection is closed...");
};
} else {
alert("WebSocket not supported by your Browser!");
}
function OpenEx() {
socket.send("{"FuncName":"DrawGraph","Param":["0"]}");
}
</script>
页面上放入一个按钮和一个图片
<div>
<input type="button" name="btn_Capture" value="拍照" οnclick="OpenEx()" />
</div>
<div>
<input type="image" name="img" id="img" />
</div>
代码有需要的可以去这里下载