使用swoole進行消息推送通知,配合vb.net進行客戶端開發同樣爽[開發篇]

  在之前的項目中,就曾據說過swoole的大名,想用來進行消息推送,可是當時只是有了初步的瞭解,並不敢大膽的運用到線上產品。所謂 識不足則多慮,威不足則多怒、因此就是怕,只能跟領導說了運用極光的推送功能,並且還說出了必定的理由,領導天然也只有相信了,那就用極光推送吧!php

  最近閒來無事,又從新溫習了一下swoole的消息通知功能,雖然在項目開發當時,也曾實現過簡單的操做的,可是此次溫習更加深了學習,配合vb.net進行開發,感受仍是棒棒噠,下面是一套實現過程,若有須要參考,請拿去,不謝!html

  首先,個人開發平臺是windows,雖然本人也裝有virtual box虛擬機,可是那玩意兒太耗內存cpu了,開起來搞實在不想搞。因此,就用了cygwin進行配置開發環境搭建,這裏我就不說具體安裝步驟了,給個連接吧,一步步按着操做就好了。 查看php在window下安裝swoole擴展的方法 請點擊。 ps: 若是你win系統裏已經安裝了一套wamp環境,在cygwin中使用php或其餘和win有相同名稱命令時,請記得使用全路徑 如:/bin/php index.php , /bin/find / -name "init*"redis

  第二步、編寫php服務端程序,命名 test_tcp_server.php , 代碼以下:數據庫

<?php
    $serv = new swoole_server("127.0.0.1", 9501);
    $serv->set(array(
        'worker_num' => 2,       //工做進程數量
        // 'daemonize' => true, //是否做爲守護進程,玩玩就不要開啓這東西了,否則你都不知道跑到哪裏去了
    ));
    $serv->on('connect', 'my_onConnect');
    $serv->on('receive', 'my_onReceive');
    $serv->on('close', 'my_onClose');
    echo "swoole_server is running on 127.0.0.1 9501 \n";
    $serv->start();

    //receive msg respond
    function my_onReceive ($serv, $fd, $from_id, $data) {
        // var_dump($serv);
        $data = trim($data);
        // 發送給誰, 如:@id msg...  , 最好的固然是使用redis或者數據庫存入號碼並生成一個映射了,不過玩玩就不要認真了
        if(substr($data, 0, 1) == '@'){
            $splitStart = strpos($data, ' ');
            $toUserId = substr($data, 1, $splitStart - 1);
            echo 'Send to:' . $toUserId . ';';
            $content = substr($data, $splitStart + 1);
            if(is_numeric($toUserId)){
                $serv->send($toUserId, "From Client[$fd@$from_id]:" . $content);
            }elseif(strtolower($toUserId) == 'all'){
                broadcast($serv, $fd, $content);
            }else{
                $serv->send($fd, 'Swoole: Unkown to user ' . strtolower($toUserId) . ' infomation.');
            }
        }else{
            echo "From Client[$fd@$from_id],received data: " . $data . PHP_EOL;
            $serv->send($fd, 'Swoole: '.$data);
        }
        // $serv->close($fd);
    }
    //connect action
    function my_onConnect ($serv, $fd){
        echo "Client:Connect. id:{$fd}\n";
    }
    //close action
    function my_onClose ($serv, $fd) {
        echo "Client: Close. id:{$fd}\n";
    }
    //broadcast except me, 只會廣播from_id相同的用戶,再研究了
    function broadcast(swoole_server $serv, $fd = 0, $data = "hello")
    {
        $start_fd = 0;
        $sendNum = 0;
        echo "broadcast to ";
        $from = "From Client[$fd]:";
        while(true)
        {
            $conn_list = $serv->connection_list($start_fd, 10);
            if($conn_list === false)
            {
                break;
            }
            var_dump($conn_list);
            $start_fd = end($conn_list);
            foreach($conn_list as $conn)
            {
                if($conn === $fd) continue;
                $ret1 = $serv->send($conn, $from . $data);
                $sendNum ++;
            }
        }
        echo $sendNum . ' numbers.';
    }

  記得把它跑起來哦windows

/bin/php test_tcp_server.php

  第三步,你能夠編寫一個客戶端程序,也能夠不用編寫,由於其餘工具也徹底能夠鏈接進行的呢!若是要定,能夠參考swoole官網的tcp_client代碼,以下:服務器

<?php
    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
    //設置事件回調函數
    $client->on("connect", function($cli) {
        $cli->send("hello world\n");
    });
    $client->on("receive", function($cli, $data){
        echo "Received: ".$data."\n";
    });
    $client->on("error", function($cli){
        echo "Connect failed\n";
    });
    $client->on("close", function($cli){
        echo "Connection close\n";
    });
    //發起網絡鏈接
    $client->connect('127.0.0.1', 9501, 0.5);

  正常的話,運行這個腳本,你就能夠收到消息瞭如:  'From Client[1@0],received data: hello,world'swoole

  第四步、你確定不知足於使用php語言去鏈接服務器端,你固然不該該知足!你還可使用windows的cmd命令行嘛,以下:網絡

telnet 127.0.0.1 9501

而後,你會發現,怎麼只輸入了一個字符就發送了。緣由是什麼win的telnet協議之類的,使用send命令,就能夠了。操做爲:按鍵 ctrl + ] ,進入telnet 命令行模式,輸入send aaaddd異步

ok,多開幾個客戶端,看起來會話就能夠了呢(要查看返回的內容,直接按Enter鍵便可,切換回來使用ctrl + ]),來看看服務端都什麼樣子吧:socket

都是有響應的吧,ok了,如今再試試一個功能, send @10 hello,10, you ok ? ,則另外一個客戶端就收到消息了

ok,到此爲止,基本上測試完成了。可是使用cmd畢竟看起來不爽,因而想到用vb.net去實現一個客戶端。代碼就簡要的貼出來,看看吧。

  第五步,使用vb.net實現客戶端訪問:

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Public Class SynchronousSocketClient
    Protected Shared port As Integer = 9501
    Protected Shared host As String = "localhost"

    Private Shared sender As Socket
    Public Shared bytes(1024) As Byte
    ' A way to the connect to the server
    Public Shared Sub Main()
        If (IsNothing(sender)) OrElse Not sender.Connected Then
            If Not IsNothing(Form1.TextBox1.Text) Then
                host = Form1.TextBox1.Text
            End If
            If (Form1.TextBox2.Text) Then
                port = Form1.TextBox2.Text
            End If
            sender = ConnectSocket(host, port)
        End If

    End Sub
    ' send something to server
    Public Shared Sub send()
        If (IsNothing(sender)) OrElse Not sender.Connected Then
            If Not IsNothing(Form1.TextBox1.Text) Then
                host = Form1.TextBox1.Text
            End If
            If (Form1.TextBox2.Text) Then
                port = Form1.TextBox2.Text
            End If
            sender = ConnectSocket(host, port)
        End If
        ' Encode the data string into a byte array.
        Dim msg As Byte() = Encoding.ASCII.GetBytes(Form1.myContent.Text)

        ' Send the data through the socket.
        Dim bytesSent As Integer = sender.Send(msg)

        ' Receive the response from the remote device.
        Dim bytesRec As Integer = sender.Receive(bytes)
        Console.WriteLine("ServerReturn = {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec))
        Form1.infoText.Text &= "ServerReturn = " & Encoding.ASCII.GetString(bytes, 0, bytesRec) & vbNewLine
    End Sub
    ' connect initialize
    Private Shared Function ConnectSocket(ByVal host As String, ByVal port As Integer) As Socket '建立鏈接 
        Dim s As Socket = Nothing
        Dim hostEntry As IPHostEntry = Nothing

        'address = System.Net.IPAddress.Parse(host)
        Dim ipHostInfo As IPHostEntry = Dns.Resolve(host)
        Dim address As IPAddress = ipHostInfo.AddressList(0)
        Dim endPoint As New IPEndPoint(address, port)
        Dim tempSocket As New Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
        tempSocket.Connect(endPoint)

        If tempSocket.Connected Then
            s = tempSocket
            Console.WriteLine("Socket connected to {0}", tempSocket.RemoteEndPoint.ToString())
            Form1.infoText.Text &= "Socket connected to " & tempSocket.RemoteEndPoint.ToString()
        End If
        Return s
    End Function
    ' close socket
    Public Shared Sub closeSocket()
        If (sender.Connected) Then
            Form1.infoText.Text &= "Socket closed : " & sender.RemoteEndPoint.ToString() & vbNewLine
            sender.Shutdown(SocketShutdown.Both)
            sender.Close()
        End If
    End Sub


End Class 'SynchronousSocketClient

如上是訪問鏈接服務器的代碼,觸發代碼則是在另外一個頁面進行的,界面以下:

運行後效果以下:

觸發事件的代碼就比較簡單了,仍是貼一下吧:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Console.WriteLine("console ", Rnd)             ' 沒法讀取最後一行console其實
        SynchronousSocketClient.Main()
        'AsynchronousClient.Main()                      ' 異步功能並未實現呢
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        infoText.Text = ""
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        SynchronousSocketClient.send()
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        SynchronousSocketClient.closeSocket()
    End Sub
End Class

  到此,打完,收工。因爲異步的調試沒有成功,就此打住吧,之後有興趣再去搞了!

相關文章
相關標籤/搜索