使用websocket-sharp来创建c#版本的websocket服务

当前有一个需求,需要网页端调用扫描仪,javascript不具备调用能力,因此需要在机器上提供一个ws服务给前端网页调用扫描仪。而扫描仪有一个c#版本的API,因此需要寻找一个c#的websocket库。

java里有大名鼎鼎的netty,通过搜索,c#可以选择websocket-sharp来实现websocket Server。

使用websocket-sharp创建websocket server

using System;
using WebSocketSharp;
using WebSocketSharp.Server;

namespace Example
{
  public class Laputa : WebSocketBehavior
  {
    protected override void OnMessage (MessageEventArgs e)
    {
      var msg = e.Data == "BALUS"
                ? "I've been balused already..."
                : "I'm not available now.";

      Send (msg);
    }
  }

  public class Program
  {
    public static void Main (string[] args)
    {
      var wssv = new WebSocketServer ("ws://dragonsnest.far");
      wssv.AddWebSocketService<Laputa> ("/Laputa");
      wssv.Start ();
      Console.ReadKey (true);
      wssv.Stop ();
    }
  }
}

Step 1

Required namespace.

using WebSocketSharp.Server;

The WebSocketBehavior and WebSocketServer 两个类需要引用 WebSocketSharp.Server namespace.

Step 2

编写处理类,需要继承 WebSocketBehavior class.

例如,如果你要创建一个echo Service,

using System;
using WebSocketSharp;
using WebSocketSharp.Server;

public class Echo : WebSocketBehavior
{
  protected override void OnMessage (MessageEventArgs e)
  {
    Send (e.Data);
  }
}

再提供一个 chat service,

using System;
using WebSocketSharp;
using WebSocketSharp.Server;

public class Chat : WebSocketBehavior
{
  private string _suffix;

  public Chat ()
    : this (null)
  {
  }

  public Chat (string suffix)
  {
    _suffix = suffix ?? String.Empty;
  }

  protected override void OnMessage (MessageEventArgs e)
  {
    Sessions.Broadcast (e.Data + _suffix);
  }
}

可以通过继承WebSocketBehavior类来自定义Service.

通过重载 WebSocketBehavior.OnMessage (MessageEventArgs) 方法, 来处理消息

同时你也可以重载 WebSocketBehavior.OnOpen (), WebSocketBehavior.OnError (ErrorEventArgs), 和 WebSocketBehavior.OnClose (CloseEventArgs) 方法,来处理websocket连接事件。

通过WebSocketBehavior.Send 方法来给客户端发送消息。

If you would like to get the sessions in the service, you should access the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

The WebSocketBehavior.Sessions.Broadcast method can send data to every client in the service.

Step 3

创建 WebSocketServer 对象.

var wssv = new WebSocketServer (4649);
wssv.AddWebSocketService<Echo> ("/Echo");
wssv.AddWebSocketService<Chat> ("/Chat");
wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));

Step 4

启动 WebSocket server.

wssv.Start ();

Step 5

停止 WebSocket server.

wssv.Stop (code, reason);

测试Demo

目的:对外提供一个websocket服务,让网页端的js可以调用扫描仪

服务端代码

 class Program
    {
        static void Main(string[] args)
        {
            var wssv = new WebSocketServer(10086);
            wssv.AddWebSocketService<ScannerHandler>("/scan");
            wssv.Start();
            if (wssv.IsListening)
            {
                Console.WriteLine("Listening on port {0}, and providing WebSocket services:", wssv.Port);
                foreach (var path in wssv.WebSocketServices.Paths)
                    Console.WriteLine("- {0}", path);
            }

            Console.WriteLine("\nPress Enter key to stop the server...");
            Console.ReadLine();

            wssv.Stop();
        }
    }

    public class ScannerHandler : WebSocketBehavior
    {
        protected override void OnMessage(MessageEventArgs e)
        {
            if(e.Data == "scan")
            {
                ScanResult result = ScanerHelper.Scan("D:\\test.jpg");
                if (result.Success)
                {
                    Console.WriteLine("scan success");
                    Send("scan success");
                }
                else
                {
                    Send("scan eror");
                }
            }
           
        }
    }

前端代码

javascript代码

    var ws;
    function initWS() {
        ws = new WebSocket("ws://127.0.0.1:10086/scan");
        ws.onopen = function () {
            console.log("Openened connection to websocket");

        };
        ws.onclose = function () {
            console.log("Close connection to websocket");
            // 断线重连
            initWS();
        }

        ws.onmessage = function (e) {
            alert(e.data)
        }
    }
    
    initWS();
    function scan() {
        ws && ws.send('scan');
    }

html代码

<button onclick="scan()">扫描</button>
  • initWS创建连接,支持断线重连
  • 可以调用scan函数,发送scan指令

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Seebug漏洞平台

Exim Off-by-one(CVE-2018-6789)漏洞复现分析

前段时间meh又挖了一个Exim的RCE漏洞[1],而且这次RCE的漏洞的约束更少了,就算开启了PIE仍然能被利用。虽然去年我研究过Exim,但是时间过去这么久...

652
来自专栏嵌入式程序猿

freeRTOS信号量学习

信号量同样是RTOS学习中很重要的一节,信号量可以用在共享资源或者同步任务中,对执行权的控制,谁拥有信号量谁拥有执行权,在freeRTOS中信号量和互斥量有点不...

2605
来自专栏何俊林

Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程

前言:前一篇的mediaPlayer框架,对于各个模块的关系,得先从核心类MediaPlayer铺开,同样看下今天的Agenda: MediaPlayer从cr...

2285
来自专栏hrscy

RxSwift - Why

官方建议总是使用 .addDisposableTo(disposeBag) 即使对于简单绑定来说那不是必要的。

582
来自专栏程序员叨叨叨

【转-干货】Retrofit2.0使用总结及注意事项

随着Google对HttpClient 摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对okHttp进行了强制依赖。Retrof...

742
来自专栏技术碎碎念

windows API 开发飞机订票系统 图形化界面 (二)

首先,用到的数据结构的定义、以及全局变量和函数的声明如下: 1 // Flight.c : 定义应用程序的入口点。 2 // 3 #include ...

3237
来自专栏EAWorld

揭秘:RESTEasy如何完美支持JAVA 微服务中的多种数据格式

本文获得stackify.com授权翻译发表,转载需要注明来自公众号EAWorld。

944
来自专栏大内老A

谈谈WCF中的Data Contract (1):Data Contract Overview

Contract in SO:Contract是对操作和数据的抽象 在我们看来,Service Orientation提供了一种对业务、功能进行分解的方式。针对...

1806
来自专栏何俊林

MediaCodec进行编解码AAC(文件格式转换)

本文来自eric原创授权发布,eric,音视频开发爱好者,简书地址:https://www.jianshu.com/u/1502591a1753。欢迎大家关注。...

3687
来自专栏Seebug漏洞平台

Exim Off-by-one(CVE-2018-6789)漏洞复现分析

前段时间meh又挖了一个Exim的RCE漏洞[1],而且这次RCE的漏洞的约束更少了,就算开启了PIE仍然能被利用。虽然去年我研究过Exim,但是时间过去这么久...

4547

扫描关注云+社区