当前位置: 移动技术网 > IT编程>开发语言>.net > UDP实现一个简易的聊天室 (Unity&&C#完成)

UDP实现一个简易的聊天室 (Unity&&C#完成)

2019年02月28日  | 移动技术网IT编程  | 我要评论

好看的电影网站,草原晨曲简谱,夜总会游戏培训

  效果展示(尚未完善)

chatudpclienttest
using system.collections;
using system.collections.generic;
using unityengine;
using system.threading;
using system.net;
using system.net.sockets;
using system.text;
using common;
using uiwidgetssamples;
using system;

/// <summary>
/// 服务端
/// </summary>
public class chatudpservertest : monobehaviour
{
    public string serverip;
    //ip地址
    public int serverport;
    //端口
    //1.创建scoket对象 ip port
    private thread thread;
    private udpclient udpseivic;
    public void start()
    {
        chatview = transform.findchildbyname("chatview").
            getcomponent<chatview>();
        //给端口和ip
        //构建终结点  ip和一个端口
        ipendpoint localep = new 
            ipendpoint(ipaddress.parse(serverip), serverport);
        udpseivic = new udpclient(localep);

        thread = new thread(receivemessage);
        thread.start();
    }
    
    /// <summary>
    /// 接收消息
    /// </summary>
    private void receivemessage()
    {
        while (true)
        {
            ipendpoint remote = new
                ipendpoint(ipaddress.any, 0);
            //创建任意终结点
            //ref
            byte[] date = udpseivic.receive(ref remote);
            //receive接收消息  如果没有收到消息 线程阻塞  放在线程中
            string msg = encoding.utf8.getstring(date);
            //获取的客户都安信息
            debug.log(remote.address + "===" + remote.port);
            //如果接收客户端的消息,会把任意终结点修改为客户端的终结点
            threadcrosshelper.instance.executeonmainthread(() => { showmessage(msg); });
        }
    }
    private chatview chatview;
    /// <summary>
    /// 显示消息
    /// </summary>
    /// <param name="msg"></param>
    public void showmessage(string msg)
    {
        chatview.datasource.add(new chatline()
        {
            username = "annns",
            message = msg,
            time = datetime.now,
            type = chatlinetype.user,
        });
    }
    private void onapplicationquit()
    {
        udpseivic.close();
        thread.abort();
    }
}
chatudpservertest

脚本引用的工具箱

  1. monosingleton (泛型单例)
  2. threadcrosshelper (为子线程提供,可以在主线程中执行的方法)
  3. transformhelper(根据名称查找后代元素)
using system.collections;
using system.collections.generic;
using unityengine;

namespace common
{
    /// <summary>
    /// 
    /// </summary>
    public class monosingleton<t> : monobehaviour where t : monosingleton<t>
    {
        //public static t instance
        //{
        //    get;
        //    private set;
        //}
        //private void awake()
        //{
        //    instance = this as t;
        //} 
        //按需加载
        private static t instance;
        public static t instance
        {
            get
            {
                if (instance == null)
                {
                    //在场景中查找对象
                    instance = findobjectoftype<t>();
                    if (instance == null)
                    {
                        //创建游戏对象 附加 脚本对象
                        new gameobject("singleton of " + typeof(t)).addcomponent<t>();//立即执行awake
                    }
                    else
                    {
                        instance.initialized();
                    }
                }
                return instance;
            }
        }

        protected virtual void initialized()
        {

        }

        [tooltip("是否需要跨场景不销毁")]
        public bool isdontdestroy = true;

        //如果管理类自行附加到物体中
        //在awake中为instance赋值 
        protected void awake()
        {
            if (isdontdestroy)
            {
                dontdestroyonload(gameobject);
            }
            if (instance == null)
            {
                instance = this as t;
                instance.initialized();
            }
        }
    }
}
monosingleton
using system;
using system.collections;
using system.collections.generic;
using unityengine;
 
namespace common
{
    /// <summary>
    /// 
    /// </summary>
    public class threadcrosshelper : monosingleton<threadcrosshelper>
    {
        /// <summary>
        /// 延迟项
        /// </summary> 
        class delayeditem
        {
            public action currentaction { get; set; }
            public datetime time { get; set; }
        }

        private list<delayeditem> actionlist;
        //private list<action> actionlist;
        //private list<float> timelist;

        protected override void initialized()
        {
            base.initialized();

            actionlist = new list<delayeditem>(); 
        }

        private void update()
        { 
            for (int i = actionlist.count - 1; i >= 0; i--)
            {
                //到时间
                if (actionlist[i].time <= datetime.now)
                {
                    lock (actionlist)
                    {
                        actionlist[i].currentaction();//执行
                        actionlist.removeat(i);//从列表中移除 
                    }
                }
            }
        }
        /// <summary>
        /// 为子线程提供,可以在主线程中执行的方法
        /// </summary>
        /// <param name="action"></param>
        /// <param name="dealy"></param>
        public void executeonmainthread(action action, float dealy = 0)
        {
            delayeditem item = new delayeditem()
            {
                currentaction = action,
                //time = time.time + dealy
                time = datetime.now.addseconds(dealy)
            };
            lock (actionlist)
            {
                actionlist.add(item);
            }
        }
    }
}
threadcrosshelper
using system.collections;
using system.collections.generic;
using unityengine;

namespace common
{
    /// <summary>
    /// 变换组件助手类
    /// </summary>
    public static  class transformhelper
    { 
        /// <summary>
        /// 未知层级,根据名称查找后代元素
        /// </summary>
        /// <param name="currenttf"></param>
        /// <param name="childname"></param>
        /// <returns></returns>
        public static transform findchildbyname(this transform currenttf, string childname)
        {
            transform childtf = currenttf.find(childname);
            if (childtf != null) return childtf;
            //将问题推迟给子物体
            for (int i = 0; i < currenttf.childcount; i++)
            {
                //在方法体内部,又遇到了相同的问题,所以需要调用自身。
                childtf = findchildbyname(currenttf.getchild(i), childname);
                if (childtf != null) return childtf;
            }
            return null;
        }
    }
}
transformhelper

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网