最近抽空玩了下ulua,挺好玩的,写了个热更新的小demo,使用的unity版本是5.3.1f,ulua版本版本是ulua_v1.24 ,服务器是用c#写的,非常简单就是接受客户端的连接然后把lua脚本传给客户端,客户端下载成功后就执行lua脚本
先展示下效果:
服务器工程:
lua代码:
客户端工程:
运行结果:
服务器:
客户端:
分割线,代码实现部分-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
服务端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace luaServer
{
class Program
{
static void Main(string[] args)
{
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("10.66.197.107"), 7000);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(ipep);
server.Listen(10);
while(true)
{
Socket client = server.Accept();
Console.WriteLine("Accept Client Ok");
string path = "E:\\UnityPrograme\\luaServer\\luaServer\\luaServer\\TuaTest.lua.txt";
FileInfo EzoneFile = new FileInfo(path);
FileStream EzoneStream = EzoneFile.OpenRead();
int PacketSize = 100000;
int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));
int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));
byte[] data = new byte[PacketSize];
for (int i = 0; i < PacketCount; i++)
{
EzoneStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
}
if (LastDataPacket != 0)
{
data = new byte[LastDataPacket];
EzoneStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
}
//client.Close();
Console.WriteLine("Send File Ok");
EzoneStream.Close();
}
}
}
}
class TransferFiles
{
public TransferFiles()
{
}
public static int SendVarData(Socket s, byte[] data) // return integer indicate how many data sent.
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(size);
sent = s.Send(datasize);//send the size of data array.
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
public static byte[] ReceiveVarData(Socket s) // return array that store the received data.
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, SocketFlags.None);//receive the size of data array for initialize a array.
int size = BitConverter.ToInt32(datasize, 0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == 0)
{
data = null;
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
}
客户端:
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System;
using System.Threading;
public class FileRecver {
public static void StartLoadLua(System.Action cb)
{
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("10.66.197.107"), 7000);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ipep);
#if UNITY_EDITOR
string fileaddr = Application.dataPath + "/luaTest.lua.txt";
#else
string fileaddr = Application.persistentDataPath + "/luaTest.lua.txt";
#endif
FileStream MyFileStream = new FileStream(fileaddr, FileMode.Create, FileAccess.Write);
byte[] data = TransferFiles.ReceiveVarData(client);
if (data.Length == 0)
{
Debug.LogError("data.Length == 0");
}
else
{
MyFileStream.Write(data, 0, data.Length);
}
MyFileStream.Close();
client.Close();
if (null != cb)
cb();
}
}
class TransferFiles
{
public TransferFiles()
{
}
public static int SendVarData(Socket s, byte[] data) // return integer indicate how many data sent.
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(size);
sent = s.Send(datasize);//send the size of data array.
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
public static byte[] ReceiveVarData(Socket s) // return array that store the received data.
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, SocketFlags.None);//receive the size of data array for initialize a array.
int size = BitConverter.ToInt32(datasize, 0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == 0)
{
data = null;
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
}
调用:
using UnityEngine;
using System.Collections;
using LuaInterface;
using System;
using System.Reflection;
public class StartUpEntry : MonoBehaviour
{
private static LuaScriptMgr lsmgr = new LuaScriptMgr();
void Awake()
{
Debug.Log("StartUpEntry Awake");
lsmgr.Start();
}
// Use this for initialization
void Start ()
{
FileRecver.StartLoadLua(delegate ()
{
Debug.Log("load lua ok");
StartCoroutine(startLoadLuaFromLocal());
});
}
private IEnumerator startLoadLuaFromLocal()
{
WWW www = new WWW("file://" + Application.dataPath + "/luaTest.lua.txt");
yield return www;
if(www.error == null)
{
lsmgr.DoString(www.text);
}
}
}