`
renzhen
  • 浏览: 251232 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用C#开发纽曼USB来电小秘书客户端小结

阅读更多
  在前面用C#开发完CRM的来电弹屏之后,有些客户有了新的要求,他们希望不但能够实现来电弹屏,更希望能够将呼入呼出的电话录音并上传到CRM服务器上,方便日后跟踪记录。于是便有了来电小秘书客户端的开发。
  来电小秘书客户端的开发是基于纽曼USB来电通客户端(详情参考:http://renzhen.iteye.com/blog/580746)的基础上进行开发的,由于纽曼USB来电通的硬件没有录音功能,于是硬件上使用了纽曼的另一个硬件产品来电小秘书,虽然是同一个厂家的产品,可是它们的API却是完全不兼容,更烦的是,来电小秘书API没有来电的回调接口,无法通过回调触发程序,也没有C#的Demo,很多功能只能通过一个不是那么详细的文档和一个Delphi的Demo摸索着做了,经历了一些挫折和困惑,终于完成了这个客户端程序。
  首先,开发要做的就是与硬件的API进行沟通,依然通过C#的P/Invoke来完成,以下是来电小秘书的P/Invoke代码。
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
    class LDT1
    {
        [DllImport("usbms.dll", EntryPoint = "LoadDRV")]
        public static extern int LoadDRV();

        [DllImport("usbms.dll", EntryPoint = "EnableCard")]
        public static extern int EnableCard();

        [DllImport("usbms.dll", EntryPoint = "StopSigCheck")]
        public static extern int StopSigCheck(int Handle);

        [DllImport("usbms.dll", EntryPoint = "ReSetUsb")]
        public static extern int ReSetUsb(int Handle);

        [DllImport("usbms.dll", EntryPoint = "HangUp")]
        public static extern int HangUp(int Handle);

        [DllImport("usbms.dll", EntryPoint = "InitDtmfBuf")]
        public static extern int InitDtmfBuf(int Handle);

        [DllImport("usbms.dll", EntryPoint = "SetDialPara")]
        public static extern int SetDialPara(UInt16 RingBack1, UInt16 RingBack0, UInt16 BusyLen, UInt16 RingTimes, UInt16 SendNoSignalLen);


        [DllImport("usbms.dll", EntryPoint = "DisableCard")]
        public static extern int DisableCard();

        [DllImport("usbms.dll", EntryPoint = "FreeDRV")]
        public static extern int FreeDRV();

        [DllImport("usbms.dll", EntryPoint = "GetDtmfCode")]
        public static extern int GetDtmfCode(UInt16 Line);

        [DllImport("usbms.dll", EntryPoint = "IsRing")]
        public static extern bool IsRing(UInt16 Line);

        [DllImport("usbms.dll", EntryPoint = "GetCallerIDStr")]
        public static extern UInt16 GetCallerIDStr(UInt16 Line, StringBuilder IDStr);


        [DllImport("usbms.dll", EntryPoint = "IsOffHook")]
        public static extern bool IsOffHook(UInt16 Line);


        [DllImport("usbms.dll", EntryPoint = "StartRecordFile")]
        public static extern bool StartRecordFile(UInt16 Line, string FileName, UInt32 dwRecordLen);

        [DllImport("usbms.dll", EntryPoint = "CheckRecordEnd")]
        public static extern bool CheckRecordEnd(UInt16 Line);


        [DllImport("usbms.dll", EntryPoint = "StopRecordFile")]
        public static extern bool StopRecordFile(UInt16 Line);

        [DllImport("usbms.dll", EntryPoint = "PCMtoWave")]
        public static extern int PCMtoWave(string SourceFileName, string TargetFileName);

        [DllImport("usbms.dll", EntryPoint = "ReadCheckResult")]
        public static extern int ReadCheckResult(int line, int mode);

        [DllImport("usbms.dll", EntryPoint = "StartSigCheck")]
        public static extern void StartSigCheck(int line);

        [DllImport("usbms.dll", EntryPoint = "ReadUsbState")]
        public static extern bool ReadUsbState(int line);

        [DllImport("usbms.dll", EntryPoint = "GetRingNum")]
        public static extern int GetRingNum(int line);

        [DllImport("usbms.dll", EntryPoint = "InitRingNum")]
        public static extern void InitRingNum(int line);

        [DllImport("usbms.dll", EntryPoint = "ReadSerialNo")]
        public static extern int ReadSerialNo(int line,StringBuilder serialNo);

    }
}

  

  然后就是关于设备状态检测了,由于没有API直接支持来电回调,所以只能自己手动的检测设备状态来判断,要实现这一部分一般有两种方式,使用Timer或者使用Thread,Delphi的Demo中使用了Timer,可是Timer实现的弊端需要使用异步的思考方式,不符合我的思维模式,灵活度也不够,而且C#创建线程太方便了,而线程是通过同步方式思考的,所以使用了Thread模式。
  然后在特定的时刻,记录电话号码、弹屏(如果是来电)、电话结束后录音和上传文件和信息到CRM服务器,其中来电号码可以很容易的获取,可是播出的号码获取就比较的麻烦了,C#中可以使用如下代码:
 
    while (LDT1.IsOffHook((ushort)this.line))
    {
          int temp = LDT1.GetDtmfCode((ushort)this.line);
           if (temp > 0)
           {
                 phonenum = phonenum + this.convertInt(temp);
            }
           Thread.Sleep(300);
                
      }

    private string convertInt(int code)
        {
            string ret="";
            switch (code)
            {
                case 10:
                    ret = "0";
                    break;
                case 11:
                    ret = "*";
                    break;
                case 12:
                    ret = "#";
                    break;
                case 13:
                    ret = "A";
                    break;
                case 14:
                    ret = "B";
                    break;
                case 15:
                    ret = "C";
                    break;
                case 16:
                    ret = "D";
                    break;
                default:
                    ret = code.ToString();
                    break;
            }
            return ret;
        }
  

  下面说一下C#中的大文件上传吧,网上有很多例子了,我参考了如下blog的代码进行开发http://www.cnblogs.com/bccu/archive/2009/01/05/1363771.html,可是无法上传成功,于是我读了一下代码,发现他将信息中的\r\n用空字符代替了,导致服务器无法识别,于是我更改了他的代码,解决了问题,代码如下:
      public static string UploadFileEx(string uploadfile, string url,
           string fileFormName, string contenttype, NameValueCollection querystring,
           CookieContainer cookies)
        {
            if ((fileFormName == null) ||
                (fileFormName.Length == 0))
            {
                fileFormName = "file";
            }

            if ((contenttype == null) ||
                (contenttype.Length == 0))
            {
                contenttype = "application/octet-stream";
            }


            string postdata;
            postdata = "?";
            if (querystring != null)
            {
                foreach (string key in querystring.Keys)
                {
                    postdata += key + "=" + querystring.Get(key) + "&";
                }
            }
            Uri uri = new Uri(url + postdata);


            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
            //webrequest.CookieContainer = cookies;
            webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
            webrequest.Method = "POST";
            string huanhang = "\r\n";
            byte[] huanhangbyte = Encoding.UTF8.GetBytes(huanhang);

            // Build up the post message header   
            StringBuilder sb = new StringBuilder();
            sb.Append("--");
            sb.Append(boundary);
            sb.Append("\r\n");
            sb.Append("Content-Disposition: form-data; name=\"");
            sb.Append(fileFormName);
            sb.Append("\"; filename=\"");
            sb.Append(Path.GetFileName(uploadfile));
            sb.Append("\"");
            sb.Append("\r\n");
            sb.Append("Content-Type: ");
            sb.Append(contenttype);
            sb.Append("\r\n");
            sb.Append("\r\n");

            string postHeader = sb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

            // Build the trailing boundary string as a byte array   
            // ensuring the boundary appears on a line by itself   
            byte[] boundaryBytes =
                   Encoding.ASCII.GetBytes("--" + boundary + "");

            FileStream fileStream = new FileStream(uploadfile,
                                        FileMode.Open, FileAccess.Read);
            long length = postHeaderBytes.Length + fileStream.Length +
                                                   boundaryBytes.Length + huanhangbyte.Length;
            webrequest.ContentLength = length;

            Stream requestStream = webrequest.GetRequestStream();

            // Write out our post header   
            requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

            // Write out the file contents   
            byte[] buffer = new Byte[checked((uint)Math.Min(4096,
                                     (int)fileStream.Length))];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                requestStream.Write(buffer, 0, bytesRead);
            requestStream.Write(huanhangbyte, 0, huanhangbyte.Length);
            // Write out the trailing boundary   
            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            fileStream.Dispose();
            requestStream.Dispose();
            WebResponse responce = webrequest.GetResponse();
            Stream s = responce.GetResponseStream();
            StreamReader sr = new StreamReader(s);
            string retval=sr.ReadToEnd();
            sr.Dispose();

            if (File.Exists(uploadfile))
            {
                try
                {
                    File.Delete(uploadfile);
                }catch(Exception e)
                {
                }
            }
            return retval;
        }

  CRM来电小秘书客户端完成了,当然要配合这个功能,服务器端CRM系统也要做一些修改,不过不是这篇文章的主要内容,关于服务器端的修改的小节,就等下次再说吧。
0
0
分享到:
评论

相关推荐

    C#开发纽曼USB来电小秘书客户端总结

    在C#中开发纽曼USB来电小秘书客户端是一项具有挑战性的任务,因为这个项目不仅要求实现来电弹屏功能,还涉及到电话录音和上传至CRM服务器。来电小秘书客户端的开发是基于纽曼的USB来电通硬件,但因为硬件的不同,...

    C#开发用SVN服务器以及客户端

    8. **冲突解决策略**:面对冲突,开发者可以使用客户端工具比较差异,手动合并,或者使用内置的冲突解决器。理解并熟练掌握冲突解决策略是使用SVN的重要技能。 9. **学习资源**:为了更好地使用SVN,开发者可以参考...

    C# 开发 websocket 服务端和客户端

    总结来说,C#开发WebSocket服务端和客户端涉及的主要知识点有:WebSocket协议原理,使用WebSocketSharp库创建WebSocket服务端和客户端,以及Windows桌面应用的系统托盘功能。通过这些知识,开发者可以构建出实时、...

    C#开发webservice接口,对客户端post服务的Json数据进行接收反馈

    C#开发webservice接口,对客户端post服务的Json数据进行接收反馈 接收到的数据流转换成string类型,有其他需求对json解析,自己写个解析去查询下. 然后反馈json发送给请求端。

    利用c#开发的餐厅点菜系统客户端

    本文将以“利用C#开发的餐厅点菜系统客户端”为主题,深入探讨这个系统的设计与实现,帮助初学者理解和掌握相关技术。 C#是一种面向对象的编程语言,由微软公司推出,广泛应用于Windows平台的软件开发,尤其适合...

    C#开发的OPC客户端程序

    标题 "C#开发的OPC客户端程序" 指向的是一个使用C#编程语言编写的OPC(OLE for Process Control)客户端应用程序。OPC是一种工业自动化领域中的标准接口,它允许不同软件之间进行数据交换,特别是在过程控制、监控和...

    MQTT客户端C#版

    **MQTT客户端C#版**是一种使用C#编程语言实现的MQTT协议客户端应用程序,它为开发者提供了一种简单易用的方式与MQTT服务器进行通信。MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅式消息传输...

    c#多线程socket开发(一个服务器对多个客户端)

    这里,我们将详细讲解如何使用C#语言开发多线程Socket服务器端程序,实现一个服务器同时与多个客户端连接对话。 多线程Socket服务器端开发 在开发多线程Socket服务器端程序时,我们需要定义一个新类,用于传递连接...

    C# Netty 客户端,服务器端包含接双向接收

    标题中的"C# Netty 客户端,服务器端包含双向接收"揭示了这是一个关于使用C#语言实现基于Netty框架的客户端和服务器端通信的项目。Netty是Java平台上的一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可...

    c#开发opc客户端

    标题 "c#开发opc客户端" 涉及到的是使用C#编程语言来创建一个OPC(OLE for Process Control)客户端的应用程序。OPC是一种工业自动化领域的标准接口,它允许不同厂商的软件和硬件系统之间进行数据交换。下面将详细...

    VS2017,C#,WinForm,WebAPI客户端+WebAPI服务端

    C#,Winform,开发的的一个示例程序,可实现WebAPI客户端发起数据POST请求,可实现WebAPI服务器响应客户端的POST请求。 WebAPI客户端,可使用钉钉和企业微信的群机器人Webhook地址,直接发起POST,实现消息推送。

    c# winform快速建websocket客户端源码 wpf快速搭建websocket客户端 c#简单建立websocket

    c# winform快速建websocket客户端源码 wpf快速搭建websocket客户端 c#简单建立websocket客户端 websocket快速简单搭建客户端 websocket客户端实现 ...使用C# WinForm结合WebSocket客户端,有以下几个显著特点和

    c# socket同步通讯 异步通讯 客户端 服务端 实例

    本文将深入探讨C#中的Socket同步通讯与异步通讯,以及如何构建客户端和服务端程序。 首先,让我们了解什么是Socket。Socket是网络通信的基本单元,它允许应用程序通过网络发送和接收数据。在C#中,Socket类位于...

    MQTT C# demo测试案例 包含服务端客户端

    C#是Microsoft开发的一种面向对象的编程语言,广泛应用于Windows平台的应用程序开发,包括服务器端和客户端软件。在这个MQTT C# demo测试案例中,我们将探讨如何使用C#来实现MQTT协议的服务器端(Broker)和客户端...

    C# MQTT服务器,客户端

    C# MQTT服务器,客户端 MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)...

    C#海康流媒体服务器+客户端Demo

    用C#写的海康DVR流媒体服务器开发,包含流媒体服务器端,客户端,实现了: 1、从DVR获取视频流并存入内存(使用NET_DVR_RealPlay_V30方法获取视频流,NET_DVR_RealPlay_V30参数中有一个回调函数,视频流处理是在回调...

    c#实现局域网服务端向客户端内多文件的传输

    c#实现局域网服务端向客户端内多文件的传输c#实现局域网服务端向客户端内多文件的传输c#实现局域网服务端向客户端内多文件的传输c#实现局域网服务端向客户端内多文件的传输c#实现局域网服务端向客户端内多文件的传输...

    基于vs2019 C# 的OPC UA客户端

    在本项目“基于vs2019 C#的OPC UA客户端”中,我们将探讨如何使用Visual Studio 2019和C#编程语言创建一个OPC UA客户端应用。 1. **OPC UA概述**: OPC UA不仅是一个通信协议,还是一套完整的技术规范,包括了数据...

    C#编写的USB通信实例(含源码)

    本资源是使用C#和DotNetUSBLib开发的USB通信实例程序,使用VS2015+Devexpress编写,可以结合我的相关博文进行学习实验

Global site tag (gtag.js) - Google Analytics