文档章节

如何通过WebSocket实现远程文件扫描

yushulx
 yushulx
发布于 2014/06/25 17:18
字数 568
阅读 578
收藏 12

当我们使用的硬件设备变得更加多元化,各种尺寸,各种系统的手机,平板,电脑会让开发消耗更多的时间和精力。因此把应用部署到服务端才是上策。

参考原文:

How to Remotely Scan Documents from PCs and Mobile Devices with HTML5 WebSocket and Dynamic .NET TWAIN

准备工作

远程获取扫描仪图像数据

初始化Dynamic .NET TWAIN组件:

dynamicDotNetTwain = new Dynamsoft.DotNet.TWAIN.DynamicDotNetTwain(); // create Dynamic .NET TWAIN component
dynamicDotNetTwain.OnPostAllTransfers += new Dynamsoft.DotNet.TWAIN.Delegate.OnPostAllTransfersHandler(this.dynamicDotNetTwain_OnPostAllTransfers); 
dynamicDotNetTwain.MaxImagesInBuffer = 64;
dynamicDotNetTwain.IfAppendImage = true;
dynamicDotNetTwain.IfThrowException = true;
dynamicDotNetTwain.IfShowUI = false;
 

在服务端查询所有可用的扫描仪,并把数据打包成JSON格式发送到Web客户端中:

int iIndex;
dynamicDotNetTwain.OpenSourceManager();
 
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter writer = new JsonTextWriter(sw))
{
    writer.Formatting = Formatting.Indented;
 
    writer.WriteStartObject();
    writer.WritePropertyName("Sources");
    writer.WriteStartArray();
    for (iIndex = 0; iIndex < dynamicDotNetTwain.SourceCount; iIndex++)
    {
        writer.WriteValue(dynamicDotNetTwain.SourceNameItems(Convert.ToInt16(iIndex)));
    }
    writer.WriteEnd();
    writer.WriteEndObject();
}
 
String msg = sw.ToString();
session.Send(msg);
 

使用JavaScript解析JSON数据:

var json = JSON.parse(data);
var jValue;
for (jProperty in json) {
    jValue = json[jProperty];
    switch (jProperty) {
        case "Sources":
            showSources(jValue);
            break;
        case "Draw":
            var w = jValue[0];
            var h = jValue[1];
            imageWidth = parseInt(w);
            imageHeight = parseInt(h);
            break;
    }
    break;
}
 

使用HTML的element和option元素来显示扫描仪列表:

var sources = document.getElementById('sources');
var option;
 
var count = values.length;
if (count == 0) {
    option = document.createElement('option');
    option.text = "N/A";
    sources.appendChild(option);
}
else {
    for (var i = 0; i < 3; i++) {
        option = document.createElement('option');
        option.text = values[i];
        sources.appendChild(option);
    };
}
 

在服务端获取文件图像:

private void appServer_NewMessageReceived(WebSocketSession session, string message)
{   
    int iIndex = Int32.Parse(message);
 
    try
    {
        dynamicDotNetTwain.CloseSource();
        bool success = dynamicDotNetTwain.SelectSourceByIndex(Convert.ToInt16(iIndex));
        dynamicDotNetTwain.OpenSource();
        dynamicDotNetTwain.AcquireImage();
    }
    catch (Dynamsoft.DotNet.TWAIN.TwainException exp)
    {
        String errorstr = "";
        errorstr += "Error " + exp.Code + "\r\n" + "Description: " + exp.Message + "\r\nPosition: " + exp.TargetSite + "\r\nHelp: " + exp.HelpLink + "\r\n";
        MessageBox.Show(errorstr);
    }
    catch (Exception exp)
    {
        String errorstr = "";
        errorstr += "ErrorMessage: " + exp.Message + "\r\n";
        MessageBox.Show(errorstr);
    }
}

图像数据准备好之后,发送到客户端:

private void dynamicDotNetTwain_OnPostAllTransfers()
        {
            if (dynamicDotNetTwain.MaxImagesInBuffer < 1)
            {
                MessageBox.Show("no image");
                return;
            }
 
            Image img = dynamicDotNetTwain.GetImage(0);
 
            ImageData imageData = load_image(img);
 
            /* send width & height in JSON */
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            using (JsonWriter writer = new JsonTextWriter(sw))
            {
                writer.Formatting = Formatting.Indented;
 
                writer.WriteStartObject();
                writer.WritePropertyName("Draw");
                writer.WriteStartArray();
                writer.WriteValue(imageData.Width);
                writer.WriteValue(imageData.Height);
                writer.WriteEnd();
                writer.WriteEndObject();
            }
            String msg = sw.ToString();
 
            IEnumerable<WebSocketSession> sessions = appServer.GetAllSessions();
            foreach (WebSocketSession session in sessions) 
            {
                session.Send(msg);
                session.Send(imageData.Data, 0, imageData.Data.Length);
            }
 
            imageData = null;
        }
 

最后在Chrome中的显示效果:

通过手机访问看到的效果:



本文转载自:http://www.codepool.biz/tech-frontier/html5/scan-documents-with-html5-websocket.html

共有 人打赏支持
yushulx
粉丝 26
博文 92
码字总数 52955
作品 0
杭州
私信 提问
spring-boot框架下的websocket服务

这几天在做web端实时展示服务端日志文件新增内容的功能。要满足实时的需求,我选择的方案是在web端跟服务端建立一个websocket链接,由服务端通过tail -f 命令将文件新增内容发送给web端。 关...

lilugoodjob
07/02
0
0
漫扯:从polling到Websocket

Http被设计成了一个单向的通信的协议,即客户端发起一个request,然后服务器回应一个response。这让服务器很为恼火:我特么才是老大,我居然不能给小弟发消息。。。 轮询   老大发火了,小...

i33
2014/08/01
0
0
SpringBoot使用WebSocket推送消息到浏览器

WebSocket 简介 WebSocket协议支持(在受控环境中运行不受信任的代码的)客户端与(选择加入该代码的通信的)远程主机之间进行全双工通信。用于此的安全模型是Web浏览器常用的基于原始的安全...

HGMrWang
09/27
0
0
结合Dynamic .NET TWAIN和Jetty,实现基于网页的TWAIN文件扫描

网页TWAIN扫描是通过多种技术结合实现的,看下流程图: 参考原文: Web-based Document Imaging Capture with .Net TWAIN and Jetty 准备工作 阅读: 如何通过jni4net,在Java应用中调用C#接...

yushulx
2014/08/18
0
0
Jetty源码学习9-WebSocket

引言 通过NIO+Continunation+HttpClient可以使Jetty具有异步长连接的功能,但有些应用场景确需要服务器“推”的功能,比如说:聊天室、实时消息提醒、股票行情等对于实时要求比较高的应用,能...

项籍20130121
2013/03/11
0
1

没有更多内容

加载失败,请刷新页面

加载更多

apache顶级项目(二) - B~C

apache顶级项目(二) - B~C https://www.apache.org/ Bahir Apache Bahir provides extensions to multiple distributed analytic platforms, extending their reach with a diversity of s......

晨猫
49分钟前
0
0
day152-2018-11-19-英语流利阅读

“超级食物”竟然是营销噱头? Daniel 2018-11-19 1.今日导读 近几年来,超级食物 superfoods 开始逐渐走红。不难发现,越来越多的轻食餐厅也在不断推出以超级食物为主打食材的健康料理,像是...

飞鱼说编程
今天
3
0
SpringBoot源码:启动过程分析(二)

接着上篇继续分析 SpringBoot 的启动过程。 SpringBoot的版本为:2.1.0 release,最新版本。 一.时序图 一样的,我们先把时序图贴上来,方便理解: 二.源码分析 回顾一下,前面我们分析到了下...

Jacktanger
昨天
3
0
Apache防盗链配置,Directory访问控制,FilesMatch进行访问控制

防盗链配置 通过限制referer来实现防盗链的功能 配置前,使用curl -e 指定referer [root@test-a test-webroot]# curl -e "http://www.test.com/1.html" -x127.0.0.1:80 "www.test.com/1.jpg......

野雪球
昨天
3
0
RxJava threading

因为Rx针对异步系统设计,并且Rx也自然支持多线程,所以新的Rx开发人员有时会假设Rx默认是多线程的。在其他任何事情之前,重要的是澄清Rx默认是单线程的。 除非另有说明,否则每次调用onNex...

woshixin
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部