C# socket 实现消息中心向消息平台 转发消息

时间:2021-12-26 10:06:07

公司用到,直接粘代码了

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Jinher.AMP.SNS.Chat.Client;
using Jinher.AMP.SNS.Chat.Deploy.CustomDTO;
using Jinher.AMP.SNS.Chat.Service;
using Jinher.AMP.SNS.Chat.Utility;

namespace Jinher.AMP.SNS.Chat.SocketManager
{
    /// <summary>
    /// 消息服务基类
    /// </summary>
    public abstract class MessageCenter
    {
        /// <summary>
        /// 表示是否连接上
        /// </summary>
        public static bool IsConnected { get; protected set; }
        /// <summary>
        /// 表示是否进行第一次握手协议
        /// </summary>
        public static bool IsHandStake { get; protected set; }
        /// <summary>
        /// 表示是否注册APP
        /// </summary>
        public static bool IsRegisterApp { get; protected set; }
        private static string _ip = string.Empty;
        ;
        private static object lockObject = new object();

        static List<byte[]> byteList = new List<byte[]>();
        //通知

        private static SocketAsyncEventArgsPool pool = null;
        private static BufferManager m_bufferManager = null;
        /// <summary>
        /// 线程休眠时间(毫秒)
        /// </summary>
        ;
        //连接对象
        private static Socket _socket = null;

        static MessageCenter()
        {
            //初始化,获取Host和Port
            _ip = System.Configuration.ConfigurationManager.AppSettings["serverip"];
            _port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["port"]);

            ";
            threadSleepTime = int.Parse(timer);
            //初始化连接对象
            InitSocket();
        }
        /// <summary>
        /// 启动消息中心
        /// </summary>
        public static void Run()
        {
            try
            {
                LogHelper.WriteLog("启动服务");
                //第一次连接服务器
                Connect();

                //保持连接
                KeepConnect();
                //推送消息队列
                //SendAsync();

                client.OnMsgReceiveed += client_OnMsgReceiveed;

            }
            catch (SocketException exception)
            {
                //socket出错
                LogHelper.WriteLog("出错", exception);
            }
            catch (Exception ex)
            {
                //未知错误
            }
            finally
            {
                //重置连接
                //ResetConnect();
            }
        }

        #region 连接服务器

        /// <summary>
        /// 连接服务器
        /// </summary>
        protected static async void Connect()
        {
            try
            {
                if (_socket == null)
                {
                    InitSocket();
                }
                LogHelper.WriteLog("开始建立连接");
                _socket.Connect(IPAddress.Parse(_ip), _port);
                LogHelper.WriteLog("连接已经建立");
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("出错了", ex);
                LogHelper.WriteLog("建立连接失败,等待重新建立连接");
                Thread.Sleep(threadSleepTime);
                Connect();
                return;
            }

            //先进行第一次握手协议
            HandShakeCmdOp();
            //注册app
            RegisterApp();

            IsConnected = true;
        }
        /// <summary>
        /// 先进行第一次握手协议
        /// </summary>
        private static void HandShakeCmdOp()
        {
            if (!IsHandStake)
            {
                LogHelper.WriteLog("开始第一次握手");
                );
                SendByInit(pmsMessage.HandShakePacket(handBytes));
                IsHandStake = true;
                LogHelper.WriteLog("成功握手");
            }

        }
        /// <summary>
        /// 注册app
        /// </summary>
        private static void RegisterApp()
        {
            //            一级命令:XNS_ROUTER
            //二级命令:REGISTER_SOCIAL_APP
            //并且规定AppId:99999999
            LogHelper.WriteLog("开始注册APP");
            string rapp = "<xns=XNS_ROUTER><cmd=REGISTER_SOCIAL_APP><appid=99999999>\0";
            //rapp += "<clienttype=3><companyid=0><userid=0>\0";
            byte[] bytes = Encoding.Default.GetBytes(rapp);

            _socket.Send(pmsMessage.RegisterPacket(bytes));
            AccpetOne();
            IsRegisterApp = true;
            LogHelper.WriteLog("注册成功");
        }

        /// <summary>
        /// 初始化连接对象
        /// </summary>
        private static void InitSocket()
        {
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        #endregion

        #region 发送消息

        /// <summary>
        /// 发送消息(异步)
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="count">表示失败重新发送次数</param>
        /// <returns></returns>
        )
        {
            //先将该消息尝试发送,如果发送失败,则连接后继续发送
            //byteList.Add(buffer);

            //启动任务,发送消息
            Task.Factory.StartNew(new Action(() =>
            {
                try
                {
                    if (_socket != null && IsConnected && _socket.Connected)
                    {
                        lock (lockObject)
                        {
                            if (_socket != null && IsConnected && _socket.Connected)
                            {
                                SendByInit(buffer);
                            }
                        }

                    }
                    else
                    {
                        byteList.Add(buffer);
                    }
                }
                catch (Exception)
                {
                    //重发一次
                    )
                    {
                        //表示失败重新发送
                        SendAsync(buffer, count + );
                    }
                }
                finally
                {

                }

            }));

        }
        /// <summary>
        /// 发送数据()
        /// </summary>
        /// <param name="buffer"></param>
        private static void SendByInit(byte[] buffer)
        {
            _socket.BeginSend(buffer, , buffer.Length, SocketFlags.None, new AsyncCallback(SendComplated), _socket);
        }

        /// <summary>
        /// 发送消息回调函数
        /// </summary>
        /// <param name="ar"></param>
        private static void SendComplated(IAsyncResult async)
        {
            try
            {
                Socket skt = async.AsyncState as Socket;
                if (skt.Connected)
                {
                    skt.EndSend(async);
                }
                LogHelper.WriteLog("发送成功");
            }
            catch (SocketException ex)
            {
                //日志文件

            }
        }

        #endregion

        #region 接受消息(方式一)

        /// <summary>
        /// 接受消息方式一
        /// </summary>
        public static void AccpetOne()
        {
            LogHelper.WriteLog("开始建立接受消息(方式一)");
            pool = );
            m_bufferManager =  *  * ,  * );
            m_bufferManager.InitBuffer();
            // 预先分配一个对象池
            SocketAsyncEventArgs readWriteEventArg;

            ; i < ; i++)
            {
                //初始化 SocketAsyncEventArgs
                readWriteEventArg = new SocketAsyncEventArgs();
                readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(Receive_Completed);
                readWriteEventArg.UserToken = new AsyncUserToken();
                // 从缓冲池分配一个字节缓冲区SocketAsyncEventArg对象
                m_bufferManager.SetBuffer(readWriteEventArg);
                // add SocketAsyncEventArg to the pool
                pool.Push(readWriteEventArg);
            }

            //取出  监视
            Receive();
        }

        private static void Receive()
        {
            SocketAsyncEventArgs readEventArgs = null;
            readEventArgs = pool.Pop();
            if (readEventArgs != null)
            {
                ((AsyncUserToken)readEventArgs.UserToken).Socket = _socket;

                _socket.ReceiveAsync(readEventArgs);
            }
        }

        private static void Receive_Completed(object sender, SocketAsyncEventArgs e)
        {
            ReceiveAsync(e);
        }
        private static void ReceiveAsync(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;
             && e.SocketError == SocketError.Success)
            {
                //echo the data received back to the client
                e.SetBuffer(, e.BytesTransferred);
                , e.BytesTransferred);
                //Console.WriteLine(tmp);
                //通知
                #region 收到消息平台发送来的消息
                //client.Send();
                )
                {
                    ProcessAccpet(e.Buffer, e.BytesTransferred);
                }
                #endregion

                //回收
                pool.Push(e);
                m_bufferManager.FreeBuffer(e);
                m_bufferManager.SetBuffer(e);
                Receive();
            }
        }

        #endregion

        #region 接受消息(方式二)
        private static void AccpetTo()
        {
            LogHelper.WriteLog("开始建立接受消息(方式二)");
            ; i < ; i++)
            {
                Task.Factory.StartNew(new Action(() =>
                {
                    try
                    {
                         * ];
                        while (true)
                        {
                            int r = _socket.Receive(bytes);
                            //通知

                            #region 收到消息平台发送来的消息

                            //client.Send();
                            )
                            {
                                //ClientSend((byte[])bytes.Clone(), r);
                                ProcessAccpet((byte[])bytes.Clone(), r);

                            }

                            #endregion

                            //string txt = Encoding.UTF8.GetString(bytes, 0, r);
                            //Console.WriteLine(txt);
                            bytes =  * ];
                        }
                    }
                    catch (SocketException ex)
                    {
                        LogHelper.WriteLog("socket出错", ex);
                        ResetConnect();
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog("出错", ex);
                    }

                }));
            }
        }

        #endregion

        #region 收到的消息进行处理
        /// <summary>
        /// 消息处理中转
        /// </summary>
        /// <param name="p"></param>
        /// <param name="r"></param>
        private static void ProcessAccpet(byte[] p, int r)
        {

            //加入日志
            //还没有进行握手,发送来的是握手包
            if (IsHandStake)
            {
                //返回去握手命令
            }
            )
            {
                LogHelper.WriteLog("收到正常消息");
                var result = pmsMessage.ReversePacketMessage(p, r);
            }
            else
            {
                LogHelper.WriteLog(string.Format("收到心跳包"));
            }

        }
        #endregion

        #region 保持连接

        /// <summary>
        /// 重置连接
        /// </summary>
        private static void ResetConnect()
        {
            LogHelper.WriteLog("=========重新连接==============");
            lock (lockObject)
            {
                IsConnected = false;
                _socket = null;
                InitSocket();
            }
            Connect();
        }

        private static Timer timer = null;
        /// <summary>
        /// 保持连接
        /// </summary>
        private static void KeepConnect()
        {
            timer = new Timer(new TimerCallback((o) =>
            {
                //发送心跳包
                SendAsync(pmsMessage.GetHeardbeat());
                LogHelper.WriteLog("已经发送心跳包");
            }), , , , ), , , , ));

        }

        #endregion

        #region 通知相关

        private static ChatClient client = ChatClient.Instance(ConfigurationManager.AppSettings["notificationUri"]);
        static PublishWebMessage pmsMessage = new PublishWebMessage();

        /// <summary>
        /// 请求发送消息
        /// </summary>
        /// <param name="msg"></param>
        protected static void client_OnMsgReceiveed(WebMessageDTO msg)
        {

            byte[] bytes = pmsMessage.PacketMessage(msg);
            SendAsync(bytes);
        }

        private static void ClientSend(byte[] buffer, int length)
        {
            MessageBase message = pmsMessage.ReversePacketMessage(buffer, length);
        }
        #endregion

    }
}

C# socket 实现消息中心向消息平台 转发消息的更多相关文章

  1. C&num; socket 实现消息中心向消息平台 转发消息 &lpar;修改&rpar;

    using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using ...

  2. IBM MQ消息中间件jms消息中RHF2消息头的处理

    公司的技术平台在和某券商对接IBM MQ消息中间件时,发送到MQ中的消息多出了消息头信息:RHF2,造成消息的接收处理不正常.在此记录此问题的处理方式. 在IBM MQ中提供了一个参数 targetC ...

  3. 如何在MFC DLL中向C&num;类发送消息

    如何在MFC DLL中向C#类发送消息 一. 引言 由于Windows Message才是Windows平台的通用数据流通格式,故在跨语言传输数据时,Message是一个不错的选择,本文档将描述如何在 ...

  4. 微信开发——微信公众平台实现消息接收以及消息的处理(Java版)

    本文主要讲述了如何在微信公众平台实现消息接收以及消息的处理,使用java语言开发,现在把实现思路和代码整理出来分先给兄弟们,希望给他们带来帮助. 温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微 ...

  5. Team Foundation 中的错误和事件消息

    Visual Studio Team System Team Foundation 中的错误和事件消息 Team Foundation 通过显示错误消息和事件消息来通知您操作成功以及操作失败.一部分错 ...

  6. ROS Learning-027 (提高篇-005 A Mobile Base-03) 控制移动平台 --- Twist 消息

    ROS 提高篇 之 A Mobile Base-03 - 控制移动平台 - Twist 消息 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu 14 ...

  7. Delphi中SendMessage使用说明(所有消息说明) good

    Delphi中SendMessage使用说明 SendMessage基础知识 函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数Po ...

  8. ASP&period;NET MVC5&plus;EF6&plus;EasyUI 后台管理系统(73)-微信公众平台开发-消息管理

    系列目录 前言 回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂 你也可以按自己所分析的情形结构来建表 必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较 ...

  9. SAP CRM 显示消息&sol;在消息中进行导航

    向用户展示消息,在任何软件中都是十分重要的. 在SAP CRM WEB UI中展示消息,不是一项很难的任务,只需要创建消息并在之后调用方法来显示它 消息类和消息号: 我在SE91中创建了如下的消息类和 ...

随机推荐

  1. MySQL数据库的事务管理

    当前在开发ERP系统,使用到的数据库为Mysql.下面介绍下如何开启事务,以及事务隔离的机制 : 1. 检查当前数据库使用的存储引擎. show engines; 2. 修改前my.ini中的文件如下 ...

  2. iOS:地图:MapKit和CoreLocation

    地图:MapKit和CoreLocation 简介: 现在很多的社交软件都引入了地图和定位功能,要想实现这2大功能,那就不得不学习其中的2个框架:MaKit和CoreLocation CoreLoca ...

  3. Ubuntu vim&plus; ctags&lpar;包含系统函数&rpar; &plus; taglist 配置 分类: vim ubuntu 2015-06-09 18&colon;19 195人阅读 评论&lpar;0&rpar; 收藏

    阅读大型代码,我们经常需要打开很多的代码文件,搜索各种定义.windows下用惯了ide的朋友,转战Linux的时候可能会觉得很难受,找不到合适的阅读工具.其实万能的vim就可以实现.下面介绍一下vi ...

  4. Java ----------- SQL语句总结(更新中。。。。。。)

    #对数据库的操作 *创建数据库 CREATE DATABASE database_name:database_name为创建的数据库的变量名称. #对表的操作

  5. Java:API文档;文档注释中的javadoc标记;官方API;自己动手给项目建一个API文档

    1.什么是API文档 在Java语言中有3种注释 //单行注释 /* 多行注释 */ /** * 文档注释 */ API(应用程序接口)文档就是用javadoc命令提取文档注释生成的,html格式,用 ...

  6. 总结描述用户和组管理类命令的使用方法&comma;系统用户相关信息,取出主机IP地址

    1.列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可. [root@db146 ~]# who|cut -f1 -d' ' |sort -u root 2.取出最后 ...

  7. Idea中运行项目时出现:未结束的字符串解决方案

    一般出现这种情况是编码不一致导致 解决办法: settings>file Encodings 编码设置成一致

  8. React中props和state相同点和不同点

    朋友们,我想死你们了,最近这几天忙着和病魔作斗争所以没怎么写博客,今天感觉好点了,赶紧来写一波,就是这木敬业. 今天我们来讨论讨论props和state相同点和不同点 首先我来概要说明一下这两者 pr ...

  9. tcp连接状态查看

    linux常用查看tcp状态工具netstat和ss,这两个工具查看时都有1个Recv-Q和Send-Q 解释如下: 对应处于Listen状态的套接字: Recv-Q表示已建立连接队列中连接个数(等待 ...

  10. HDU 1028 HDU 1398 (母函数)

    题意:输入一个n  给出其所有组合数 如: 4 = 4;  4 = 3 + 1;  4 = 2 + 2;  4 = 2 + 1 + 1;  4 = 1 + 1 + 1 + 1; 重复不算 母函数入门题 ...