如何构建C#SIP SMS示例

本文介绍了如何构建一个使用C#的SIP SMS示例程序,利用Ozeki SDK和Windows Forms技术。程序能自动注册到SIP PBX,拨打电话,接收电话,发送和接收DTMF信号,同时具备发送短信功能。示例代码详细展示了电话线注册、呼叫处理、DTMF信号发送以及SIP消息通知的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SIP SMS示例

SIP消息的重要性很高,因为它们经常用于各种目的。 它们用于建立电话,采取补充行动等。今天,当我们生活在一个瞬息万变的世界中时,快速高效的沟通比以往任何时候都更为重要。 SMS技术提供了相互之间发送信息的最快方法之一。 这样,您绝对可以确定收件人会收到您的消息,因为大多数人都将手机放在附近。

开发此示例程序旨在为此类问题提供有效的解决方案。 在开发过程中,我使用了Ozeki提供的SDK和Microsoft Windows Forms演示技术。

我开发了一种电话,可以转发和接收电话,并且还可以发送和接收DTMF信号以在IVR系统中导航。

程序运行

运行该程序后,电话将使用给定的SIP帐户自动注册到给定的SIP PBX。 如果在显示屏上成功完成注册过程,则可以看到成功的注册。 从现在开始,softpohne准备拨打,接听电话,并且可以在通话期间发送,接收DTMF信号以在IVR系统中导航。 (示例程序的源代码包含取决于环境的设置,因此下载后不要忘记对其进行自定义)。 通话结束后,会收到有关关键字的通知。

文件后面的PhoneMain.cs代码记下与界面相关的启动事件,并将逻辑连接到GUI。 该示例程序缺少设计示例和其他专有属性,并且由于其仅用于演示,因此侧重于简单性。 这意味着PhoneMain.cs文件包含示例程序的完整逻辑。 打开文件时,您会看到使用Ozeki VoIP SIP SDK所需的几行声明。

public partial class PhoneMain : Form
    {
        ISoftPhone softPhone;
        IPhoneLine phoneLine;
        PhoneLineInformation phoneLineInformation;
        IPhoneCall call;
        OzPipeStream speakerStream;
        ozWavePlayer wavePlayer;
        ozWaveRecorder waveRecorder;
        bool inComingCall;
        Stream ReceivedStream;
        Stream SentStream;
软电话

它代表电话,其电话线由IphoneLine代表。 电话线可能更多,这意味着我们可以开发多线电话。

Iphoneline

它代表可以注册到SIP PBX(例如Asterisk,3CX)或SIP提供商提供的其他PBX的电话线。 注册通过SIP帐户进行。

电话线信息

这是一个枚举类型,表示PBX上电话线的状态。 例如,已注册,未注册,成功/失败注册。

手机通话

它代表一个呼叫:呼叫的状态,呼叫的方向,在哪条电话线上创建的,被叫的人等等。

OzPipeStream

这是一个可选设备,它有助于处理来自另一方的传入声音数据。

ozWavePlayer

它在扬声器上播放接收到的声音数据。

ozWavRecorder

它处理来自操作系统默认输入设备(麦克风)的声音数据。

接收流

流是保存接收到的流的流。

发送流

流将保存发送的流。

从而将其分配给Windows窗体窗口的“已加载”事件,并在加载“ PhoneMain”窗口后,可以启动Ozeki SDK软电话的初始化和注册。

private void InitializeSoftPhone()
        {
            softPhone = SoftPhoneFactory.CreateSoftPhone("192.168.91.42", 5700, 5750, 5780);
            softPhone.IncommingCall += new EventHandler<VoIPEventArgs<IPhoneCall>>(softPhone_IncommingCall);
            phoneLine = softPhone.CreatePhoneLine(new SIPAccount(true, "oz891", "oz891", "oz891", "oz891", "192.168.91.212", 5060));
            phoneLine.PhoneLineInformation += new EventHandler<VoIPEventArgs<PhoneLineInformation>>(phoneLine_PhoneLineInformation); 
            softPhone.RegisterPhoneLine(phoneLine);
        } 
SDK表示通过IpPhoneCall接口的传入和传出呼叫。 此界面包含给定呼叫的状态,在哪条线路上被创建以及谁是被呼叫者。 在此对象上,您可以接听或挂断电话。 让我们看看示例程序的事件。

对于拨出电话,我们提供要拨打的号码。 然后按代答按钮,通话开始。 界面按钮是针对触发器的,因此在“ Pick Up”按钮的情况下让我们看一下。

private void buttonPickUp_Click(object sender, EventArgs e)
        {
            if (inComingCall)
            {
                inComingCall = false;
                call.Accept();
                return;
            } 
            if (call != null)
                return; 
            if (string.IsNullOrWhiteSpace(labelDialingNumber.Text))
                return; 
            if (phoneLineInformation != PhoneLineInformation.RegistrationSucceeded && phoneLineInformation != PhoneLineInformation.NoRegNeeded)
            {
                MessageBox.Show("Phone line state is not valid!");
                return;
            } 
            call = softPhone.Call(phoneLine, labelDialingNumber.Text);
            WireUpCallEvents();
            call.Start();
        }

在下面,您可以看到我是如何接线的。

private void WireUpCallEvents()
        {
            call.CallStateChanged += new EventHandler<VoIPEventArgs<CallState>>(call_CallStateChanged);
            call.MediaDataReceived += new EventHandler<VoIPEventArgs<VoIPMediaData>>(call_MediaDataReceived);
            call.DtmfReceived += new EventHandler<VoIPEventArgs<Tuple<VoIPMediaType, DtmfSignal>>>(call_DtmfReceived);
            call.CallErrorOccured += new EventHandler<VoIPEventArgs<CallError>>(call_CallErrorOccured);
        }

通过CallErrorOccured事件,接收有关未创建的原因的信息。 它们可以是:呼叫被拒绝,被叫方正忙,被叫号码不可用或该号码不存在。

为了解决这些重要事件,请启动一个真正的电话。 您可以使用调用对象的“启动”功能来实现。 在示例中是“ call.Start()”行。

Ozeki VoIP SIP SDK通过“ ISoftphone” InComingCall事件公开传入的呼叫。

private void softPhone_IncommingCall(object sender, VoIPEventArgs<IPhoneCall> e)
        {
            InvokeGUIThread(()=>
                         {
                             labelCallStateInfo.Text = "Incoming call";
                             labelDialingNumber.Text = String.Format("from {0}", e.Item.DialInfo);
                             call = e.Item;
                             WireUpCallEvents();
                             inComingCall = true;
                         });
        } 
上面显示的代码示例对此进行了处理,如果有来电,它将在显示屏上发出呼叫信号。 然后注册来电的必要事件。 如果是呼出电话或呼入电话,则呼入电话变量会发出“ Pick Up”按钮的信号。

“挂断”按钮也连接到事件处理程序,类似于“拾取”按钮。 如下所示的事件处理程序将结束通话,您只需按“挂断”按钮即可。

private void buttonHangUp_Click(object sender, EventArgs e) 
     {
            if (call != null)
            {   
                inComingCall = false;
                call.HangUp();
                call = null;
            }
            labelDialingNumber.Text = string.Empty;
        }

Ozeki VoIP SIP SDK提供有关呼叫状态的信息。 它们可以是:InCall,完成,拒绝,响铃等。通过CallStateChange事件,将显示这些呼叫状态。 该示例程序无法处理所有可能性,因为我只专注于重要的可能性。 根据这些重要程序,可以轻松创建其他程序。


private void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
        {
            InvokeGUIThread(() => { labelCallStateInfo.Text = e.Item.ToString(); }); 
            switch (e.Item)
            {
               ozWaveFormat waveFormat = new ozWaveFormat(8000, 16, 1);
          ReceivedStream = new ozWaveFileWriter(waveFormat, receivedFilePath);
              SentStream = new ozWaveFileWriter(waveFormat, sentFilePath); 
              waveRecorder = new ozWaveRecorder();
              waveRecorder.DataArrived += waveRecorder_DataArrived;
              waveRecorder.StartRecording(); 
              speakerStream = new OzPipeStream();
              wavePlayer = new ozWavePlayer(speakerStream);
              wavePlayer.Play();
              break;
                case CallState.Completed:
                    waveRecorder.Dispose();
                    speakerStream.Dispose();
                    speakerStream = null;
                    wavePlayer.Dispose(); 
                    call = null;
                    InvokeGUIThread(() => { labelDialingNumber.Text = string.Empty; });
                    break;
                case CallState.Cancelled:
                    call = null;
                    break;
            }        } 
由于在“呼叫” MediaDataReceived的输出/传入线路上,传入的PCM声音数据仅需要转发到声音系统,如下所示。
private void call_MediaDataReceived(object sender, VoIPEventArgs<VoIPMediaData> e)
        {
            if (speakerStream != null)
                speakerStream.Write(e.Item.PCMData, 0, e.Item.PCMData.Length);
       if (ReceivedStream.CanWrite)
            {
                ((ozWaveFileWriter)ReceivedStream).Save(e.Item.PCMData);
            }
        } 
将源自麦克风的PCM声音数据传递到代表实际呼叫的呼叫对象。 这是通过SendMediaData的过程发生的,声音将根据构建的通信通道发送。 声音数据将在正确的声音编解码器的帮助下进行压缩,然后将其转发给接收者。
private void waveRecorder_DataArrived(object sender, ozDataArrivedEventArgs e)
        {
            if (call != null)
                call.SendMediaData(VoIPMediaType.Audio, e.Data);
       if (SentStream.CanWrite)
            {
                ((ozWaveFileWriter)SentStream).Save(e.Data);
            }
        }

建立呼叫后,就有机会发送DTMF信号。 您可以在被叫客户服务的IVR系统中导航。 Ozeki VoIP SIP SDK以一种简单的方式发送DTMF信号。 在表示当前调用的对象上调用“ StartDTMFSignal”方法,如下所示。


private void buttonKeyPadButton_MouseDown(object sender, MouseEventArgs e)
        {
            if (call != null && call.CallState == CallState.InCall)
            {
                var btn = sender as Button;
                if (btn != null)
                {
                    int id; 
                    if (btn.Tag != null && int.TryParse(btn.Tag.ToString(), out id))
                    {
                        call.StartDTMFSignal(VoIPMediaType.Audio, id);
                    }
                }
            }
        }  
结束DTMF信号类似于开始。 在表示当前调用的对象上,邀请“ StopDTMFSignal”方法。 在此下方可以看到,其中id是参考编号类型DTMF信号,并且与按下的按钮有关。
call.StopDTMFSignal(VoIPMediaType.Audio, id);

Ozeki VoIP SIP SDK以一种简单的方式通知SIP消息的内容。 为此,将事件分配给如下所示的事件。

OzSIP.Log.SIPMessageLogger.NewSIPMessage += SIPMessageLogger_NewSIPMessage;

现在检查消息内容

void SIPMessageLogger_NewSIPMessage(object sender, VoIPEventArgs<string> e)
  { 
    if (e.Item.Contains(txb_SIPText.Text))
      {
         SendSMS();
      }
  }

如果搜索到的SIP文本片段匹配,则只需要发送一条SMS。 可以通过发送到SMS服务器的http API的请求来实现

private void SendSMS()
 {
   string url =
   string.Format(@"http://{0}/api?action=sendmessage&username={1}&password={2}&recipient={3}&messagetype=SMS:TEXT&messagedata={4}",Txb_IpAddress.Text, txb_UserName.Text, Txb_Password.Text, Txb_recipient.Text, Txb_SmsText.Text); 
   WebRequest request = WebRequest.Create(url); 
   request.GetResponse();
 }
摘要

短信发送已成为我们生活的一部分,就像手机,电视或互联网一样。 这是一种非常有效且快速的通讯方式。 实现很简单,因此很容易创建自己的C#SIP SMS示例。 可以在网页上找到更多特定信息。 我只能向所有人推荐此解决方案。

From: https://bytes.com/topic/c-sharp/insights/913600-how-build-c-sip-sms-example

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值