Unity/Tuanjie 在微信小游戏使用udp通信
一般来讲,微信小游戏与web页面类似。我们在网页中更习惯的是使用websocket进行通信。Websocket本身是基于TCP进行封装的,在确定TCP达不到我们要求的延迟时,我们只能选择使用UDP。这边参考微信小游戏的来实现一个简单的Demo。首先,由于UDP是面向无连接的,只是单方向发送报文信息,没有Response,我们怎么才能确认UDP信息呢。我们用Go实现一个简单的UDP Server,收
·
起因
一般来讲,微信小游戏与web页面类似。我们在网页中更习惯的是使用websocket进行通信。Websocket本身是基于TCP进行封装的,在确定TCP达不到我们要求的延迟时,我们只能选择使用UDP。
这边参考微信小游戏的UDP文档来实现一个简单的Demo。
首先,由于UDP是面向无连接的,只是单方向发送报文信息,没有Response,我们怎么才能确认UDP信息呢。我们用Go实现一个简单的UDP Server,收到什么消息就返回什么消息,将客户端发送和接收到的信息进行对比就知道了。
Go UDP Server
package main
import (
"fmt"
"net"
)
func main() {
// 创建一个UDP地址
addr, err := net.ResolveUDPAddr("udp", ":8101")
if err != nil {
fmt.Println("Error resolving UDP address:", err)
return
}
// 创建一个UDP连接
conn, err := net.ListenUDP("udp", addr)
if err != nil {
fmt.Println("Error listening on UDP port:", err)
return
}
defer conn.Close()
fmt.Println("UDP Server is listening on :8101")
buffer := make([]byte, 1024)
for {
// 读取数据
n, clientAddr, err := conn.ReadFromUDP(buffer)
if err != nil {
fmt.Println("Error reading from UDP:", err)
continue
}
// 打印接收到的数据
fmt.Printf("Received message from %s: %s\n", clientAddr, string(buffer[:n]))
// 发送相同的消息回客户端
_, err = conn.WriteToUDP(buffer[:n], clientAddr)
if err != nil {
fmt.Println("Error sending response to UDP:", err)
continue
}
fmt.Printf("Sent response to %s: %s\n", clientAddr, string(buffer[:n]))
}
}
Unity UDP Demo
在这个方法里面,对应外面一个叫Addr的InputFiled,用来输入 <ip:port>,然后我们依次调用 Listen, connect, write/send, close四个方法,对应的监听UDP端口,连接到对应的<ip:port>, 发送消息,支持发送string或者byte, 以及关闭端口四个方法。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using LitJson;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using WeChatWASM;
public class TestUDPConnect : MonoBehaviour
{
private static WXUDPSocket _udpSocket;
private bool _connected = false;
// 数据
private string _stringData = "hello, how are you";
private byte[] _bufferData = { 66, 117, 102, 102, 101, 114, 32, 68, 97, 116, 97, 32 };
public TMP_InputField AddrInputField;
private void Start()
{
AddrInputField = GameObject.Find("Addr").GetComponent<TMP_InputField>();
}
public void Listen()
{
AddrInputField = GameObject.Find("Addr").GetComponent<TMP_InputField>();
Debug.Log(AddrInputField.text);
WX.InitSDK((int code) =>
{
Debug.Log("InitSDK code: " + code);
});
if (_udpSocket == null)
{
_udpSocket = WX.CreateUDPSocket();
var port = _udpSocket.Bind();
Debug.Log("port: " + port);
Debug.Log("udpSocket: " + JsonUtility.ToJson(_udpSocket));
_udpSocket.OnListening(
(res) =>
{
Debug.Log("onListening: " + JsonUtility.ToJson(res));
}
);
_udpSocket.OnError(
(res) =>
{
Debug.Log("onError: " + JsonUtility.ToJson(res));
}
);
_udpSocket.OnClose(
(res) =>
{
Debug.Log("onClose: " + JsonUtility.ToJson(res));
}
);
_udpSocket.OnMessage(
(res) =>
{
Debug.Log("onMessage: " + JsonUtility.ToJson(res));
}
);
}
else
{
Debug.LogError("udp实例已初始化");
}
}
public void connect()
{
if (_udpSocket != null && !_connected)
{
AddrInputField = GameObject.Find("Addr").GetComponent<TMP_InputField>();
var arr = AddrInputField.text.Split(':');
_udpSocket.Connect(
new UDPSocketConnectOption() { address = arr[0], port = Convert.ToInt32(arr[1]) }
);
_connected = true;
}
else
{
Debug.LogError("连接失败:udp实例未初始化或已连接");
}
}
public void writeString()
{
write("String");
}
public void sendString()
{
send("String");
}
private void write(string type)
{
if (_udpSocket != null && _connected)
{
AddrInputField = GameObject.Find("Addr").GetComponent<TMP_InputField>();
var arr = AddrInputField.text.Split(':');
Debug.Log(AddrInputField);
UDPSocketSendOption option = new UDPSocketSendOption()
{
address = arr[0],
port = Convert.ToInt32(arr[1])
};
if (type == "String")
{
option.message = _stringData;
}
else
{
option.message = _bufferData;
}
_udpSocket.Write(option);
Debug.Log("Message: " + option.message);
}
else
{
Debug.LogError("write失败:udp实例未初始化或未连接");
}
}
private void send(string type)
{
if (_udpSocket != null)
{
AddrInputField = GameObject.Find("Addr").GetComponent<TMP_InputField>();
var arr = AddrInputField.text.Split(':');
UDPSocketSendOption option = new UDPSocketSendOption()
{
address = arr[0],
port = Convert.ToInt32(arr[1])
};
if (type == "String")
{
option.message = _stringData;
}
else
{
option.message = _bufferData;
}
_udpSocket.Send(option);
Debug.Log("Message: " + option.message);
}
else
{
Debug.LogError("send失败:udp实例未初始化");
}
}
public void close()
{
if (_udpSocket != null && _connected)
{
_udpSocket.Close();
_connected = false;
_udpSocket = null;
}
else
{
Debug.LogError("关闭失败:udp实例未初始化或未连接");
}
}
}
更多推荐
所有评论(0)