使用swoole进行消息推送通知,配合vb.net进行客户端开发一样爽[开发篇]
在以前的项目中,就曾听说过swoole的大名,想用来进行消息推送,但是当时只是有了初步的了解,并不敢大胆的运用到线上产品。所谓 识不足则多虑,威不足则多怒、所以就是怕,只能跟领导说了运用极光的推送功能,而且还说出了一定的理由,领导自然也只有相信了,那就用极光推送吧!
最近闲来无事,又重新温习了一下swoole的消息通知功能,虽然在项目开发当时,也曾实现过简单的操作的,但是这次温习更加深了学习,配合vb.net进行开发,感觉还是棒棒哒,下面是一套实现过程,如有需要参考,请拿去,不谢!
首先,我的开发平台是windows,虽然本人也装有virtual box虚拟机,但是那玩意儿太耗内存cpu了,开起来搞实在不想搞。所以,就用了cygwin进行配置开发环境搭建,这里我就不说具体安装步骤了,给个链接吧,一步步按着操作就行了。 查看php在window下安装swoole扩展的方法 请点击。 ps: 如果你win系统里已经安装了一套wamp环境,在cygwin中使用php或其他和win有相同名称命令时,请记得使用全路径 如:/bin/php index.php , /bin/find / -name "init*"
第二步、编写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.';
- }
记得把它跑起来哦
- /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'
第四步、你肯定不满足于使用php语言去连接服务器端,你当然不应该满足!你还可以使用windows的cmd命令行嘛,如下:
- telnet 127.0.0.1
然后,你会发现,怎么只输入了一个字符就发送了。原因是什么win的telnet协议之类的,使用send命令,就可以了。操作为:按键 ctrl + ] ,进入telnet 命令行模式,输入send aaaddd
ok,多开几个客户端,看起来会话就可以了呢(要查看返回的内容,直接按Enter键即可,切换回来使用ctrl + ]),来看看服务端都什么样子吧:
都是有响应的吧,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 =
- Protected Shared host As String = "localhost"
- Private Shared sender As Socket
- Public Shared bytes() 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, , bytesRec))
- Form1.infoText.Text &= "ServerReturn = " & Encoding.ASCII.GetString(bytes, , 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()
- 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
到此,打完,收工。由于异步的调试没有成功,就此打住吧,以后有兴趣再去搞了!
使用swoole进行消息推送通知,配合vb.net进行客户端开发一样爽[开发篇]的更多相关文章
- .NET向APNS苹果消息推送通知
一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...
- How Javascript works (Javascript工作原理) (九) 网页消息推送通知机制
个人总结: 1.介绍了网页消息推送通知机制 全文地址:https://github.com/Troland/how-javascript-works 这是 JavaScript 工作原理的第九章. 现 ...
- vue中使用stompjs实现mqtt消息推送通知
最近在研究vue+webAPI进行前后端分离,在一些如前端定时循环请求后台接口判断状态等应用场景用使用mqtt进行主动的消息推送能够很大程度的减小服务端接口的压力,提高系统的效率,而且可以利用mqtt ...
- swoole WebSocket 消息推送
server.php <?php //连接本地的 Redis 服务 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $r ...
- Windows Azure Service Bus Notification Hub推送通知
前言 随着Windows Azure 在中国的正式落地,相信越来越多的人会体验到Windows Azure带来的强大和便利.在上一篇文章中, 我们介绍了如何利用Windows Azure中的Servi ...
- Android客户端消息推送原理简介
首先简单介绍一下Android消息推送的主要三种方式,如果你已经看过类似的文章,请直接忽略三种介绍. 1.使用SMS服务,即服务器端发送短信,然后手机客户端监听短信的广播,然后对数据进行一定的处 ...
- ios 消息推送流程 转载
iOS开发:推送通知简述及开发实践热度 1已有 706 次阅读 2013-10-15 09:23 |个人分类:经验之谈|系统分类:ios| IOS, 推送一.关于推送通知 推送通知,也被叫做远程通知, ...
- IOS 基于APNS消息推送原理与实现(JAVA后台)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple Pu ...
- (转)苹果推送通知服务教程 Apple Push Notification Services Tutorial
本文译自http://www.raywenderlich.com/.原文由iOS教程团队 Matthijs Hollemans 撰写,经原网站管理员授权本博翻译. 在iOS系统,考虑到手机电池电量,应 ...
随机推荐
- 修改git以往历史中所有commit的name和email
当换了新的电脑设备或者在 homestead 中使用 git 的时候:如果忘了 git config 设置用户名和邮箱:这样当 git commit 的时候就会使用设备名作为 git 用户名:或者我们 ...
- javascript正则表达式中 (?=exp)、(?<=exp)、(?!exp)
(?=exp) 百度百科给的解释:非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用.例如,“Windows(?=95|98|NT|2000) ...
- html 中使用 iconfont、fontAwesome
在HTML中尽量使用iconfont 替代图片有很多好处,而且方便,可以设置大小.颜色 等 可以用于字体的设置. 一.使用iconfont 1.打开iconfont 官网 iconfont.cn. 2 ...
- 小程序微信支付java
https://blog.csdn.net/qq_33452819/article/details/70314204#
- Linux查看某个端口的连接数
一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数 netstat -nat | grep -i "80" | wc -l 2)统计ht ...
- WMS接口平台配置培训
供应链管理平台地址:https://twms.ninestargroup.com/ibus/#/processconfig?scShortcutld=3_17__1_303 WMS提供WSWMS固定的 ...
- Linux mysql 联表查询
在rhce考试题中,第21.22题为数据库查询题 题目: 在system1上创建一个Maria DB数据库,名为Contacts,要求: 数据库应该包含来自数据库users.mdb的内容,数据库只能被 ...
- 转)Ubuntu16.04下安装DDD(Data Display Debugger)
以下转自:http://www.linuxdiyf.com/linux/26393.html 前两天在Linux论坛偶然间看到了DDD这个软件,根据介绍是一个gdb界面化的调试软件,这正是我找了好 ...
- 322. Coin Change选取最少的硬币凑整-背包问题变形
[抄题]: You are given coins of different denominations and a total amount of money amount. Write a fun ...
- [leetcode]46. Permutations全排列(给定序列无重复元素)
Given a collection of distinct integers, return all possible permutations. Input: [1,2,3] Output: [ ...