UDP实现一个简易的聊天室 (Unity&&C#完成)
程序员文章站
2022-04-28 12:24:26
效果展示(尚未完善) using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Threading; using System.Net; using System.Net.S ......
效果展示(尚未完善)
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(); } }
脚本引用的工具箱
- monosingleton (泛型单例)
- threadcrosshelper (为子线程提供,可以在主线程中执行的方法)
- 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(); } } } }
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); } } } }
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; } } }