亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Unity使用Websocket實現WebGL在線游戲(無插件)

2019-11-14 13:38:01
字體:
來源:轉載
供稿:網友
開篇
 
Unity支持WebGL之前,想做頁游的話需要轉換成Flash平臺發布,但是很麻煩中間會有很多東西需要特殊處理?;蛘卟皇褂肍lash那就需要Unity 的 WebPlayer,這是一個Web插件,運行之前要先在瀏覽器上安裝此插件,才可以運行Unity程序。
BUT!!!現在Unity可以直接翻譯成JS在瀏覽器上使用WebGL進行渲染,哈哈,Nice。解決了頁游插件問題。但是聯網呢?傳統的Socket方式肯定不行,瀏覽器不會讓你用Socket進行傳輸的。然兒HTML5還有一個新特性就是Websocket,可以在瀏覽器上建立Socket長連接了。怎么實現呢?鄙人嘗試了很多方式,最后發現一個真正可行的方式,而且貌似只有這樣才可以,遂分享之~~~
 
實踐
 
?。?!DEMO全源碼http://www.49028c.com/yinlong1991/p/5090289.html ?。?!
我先描述下大概的邏輯:
Unity可以調用Web JS,然后JS里面使用WebSocket連接服務器,Websocket通過SendMessage給Unity 發回收到的消息包。代碼如下:
    /*---------------- WebGl Platform ---------------------*/    [DllImport("__Internal")]    PRivate static extern void ConnectJS(string str);    [DllImport("__Internal")]    private static extern void SendMsgJS(byte[] data,int length);    [DllImport("__Internal")]    private static extern void CloseJS();    [DllImport("__Internal")]    private static extern void AlertJS(string str);     private void Connect_2(string str)    {        ConnectJS(str);    }     private void SendMsg_2(MessageBase msg)    {        byte[] data = SerializeMsg(msg);        SendMsgJS(data,data.Length);    }     private void Close_2()    {        CloseJS();    }     private void OnOpen_2()    {        OnOpen();    }     private void OnMessage_2(string msg)    {        string []byteIntS = msg.Split(' ');        byte[] data = new byte[byteIntS.Length];        for (int i = 0; i < byteIntS.Length; i++)        {            data[i] = (byte)int.Parse(byteIntS[i]);        }        OnMessage(data);    }     private void OnClose_2()    {        OnClose();    }    /*--------------------- Serialze ------------------------*/    BinaryFormatter binFormat = new BinaryFormatter();//創建二進制序列化器    private byte[] SerializeMsg(MessageBase msg)    {        MemoryStream stream = new MemoryStream();        binFormat.Serialize(stream, msg);        return stream.GetBuffer();    }

 Web端使用的jslib,此文件要放在Plugins目錄下,會被翻譯成JS代碼在瀏覽器上運行。我的路徑是:Assets/Plugins/WebGL/WebsocketJS.jslib

var WebsocketJS = {	$webSocket:{},	ConnectJS : function(url)	{		var s_url = Pointer_stringify(url);		webSocket = new WebSocket(s_url);		webSocket.onmessage = function (e) 		{			if (e.data instanceof Blob)			{				var reader = new FileReader();				reader.addEventListener("loadend", function() 				{					var array = new Uint8Array(reader.result);					var msg = "";					for(var i = 0;i<array.length;i++)					{						if(i == array.length - 1)							msg += array[i];						else							msg += array[i]+" ";					}					SendMessage("WebSocket","OnMessage_2",msg);				});				reader.readAsArrayBuffer(e.data);			}			else			{				alert("msg not a blob instance");			}		};		webSocket.onopen = function(e)		{			SendMessage("WebSocket","OnOpen_2");		};		webSocket.onclose = function(e)		{			SendMessage("WebSocket","OnClose_2");		};	},	SendMsgJS: function (msg,length)	{		webSocket.send(HEAPU8.buffer.slice(msg, msg+length));	},		CloseJS: function ()	{		webSocket.close();	},		AlertJS:function (msg)	{		var s_msg = Pointer_stringify(msg);		alert(s_msg);	}};autoAddDeps(WebsocketJS, '$webSocket');mergeInto(LibraryManager.library, WebsocketJS);

 注意jslib的寫法格式比較特殊,$webSocket:{}, 表示聲明一個全局變量,autoAddDeps(WebsocketJS,'$webSocket'); 這個是使用該變量?反正要Add進去。

這里面所有的函數都是由Unity來調用的如上面的C#代碼:private static extern void ConnectJS(string str); 這樣的寫法,就可以調用JS方法了。
細節:
    var s_url =Pointer_stringify(url); 所有的str類型內容在這里面要使用Pointer_stringify 函數轉化一下。
    HEAPU8.buffer.slice(msg, msg+length) 所有byte[]類型的數據需要用HEAPU8.buffer.slice(byte[] data,int length)函數來轉化。
    還有一些其他的數據類型轉化,暫時沒用到不詳細解釋,需要可也參考他人代碼:https://github.com/hecomi/UWO/blob/master/Assets/Plugins/WebSocket.jslib 丫的這是國外網站最流行的一段jslib代碼,但是我覺得不好?。?!
重點要說一下 webSocket.onmessage 方法體的內容
if (e.data instanceof Blob){	var reader = new FileReader();	reader.addEventListener("loadend", function() 	{		var array = new Uint8Array(reader.result);		var msg = "";		for(var i = 0;i<array.length;i++)		{			if(i == array.length - 1)				msg += array[i];			else				msg += array[i]+" ";		}		SendMessage("WebSocket","OnMessage_2",msg);	});	reader.readAsArrayBuffer(e.data);}

 從代碼中可以看出來接收到的數據是Blob塊類型的,然后通過FileReader讀字節流,然后把字節流轉換成8位無符號整形數組 Uint8Array 然后放入到字符串里以空格間隔,為什么要這么寫呢?,這樣豈不是大大的增加了數據傳輸量(PS:非網絡流量傳輸,只是JS到Unity之間)。原因是我要通過 SendMessage("WebSocket","OnMessage_2",msg); 函數吧數據串給Unity,我查了一大頓的文檔居然這貨不支持除了string類型的其他所有數據類型的傳輸,非文本類型的字符也不能傳輸比如'/0'字符就傳輸失敗。我擦嘞,那我只能用如上所述的暴力方式封裝String類型的字符串,然后到Unity中再去做解析了。這塊也是為什么上面我說外國網站上用的那種jslib讀取網絡數據包不好的地方。

外國網站上的傳輸方式:
C#代碼:
[DllImport("__Internal")]private static extern void SocketRecv (int socketInstance, IntPtr ptr, int length);[DllImport("__Internal")]private static extern int SocketRecvLength (int socketInstance); public byte[] Recv(){	int length = SocketRecvLength (m_NativeRef);	if (length == 0)		return null;	byte[] buffer = new byte[length];	IntPtr unmanagedPointer = Marshal.AllocHGlobal(length);	SocketRecv (m_NativeRef, unmanagedPointer, length);	Marshal.Copy (unmanagedPointer, buffer, 0, length);	Marshal.FreeHGlobal(unmanagedPointer);	return buffer;}

 jslib代碼:

SocketSend: function (socketInstance, ptr, length){	var ptr = HEAPU32[ptr>>2];	var socket = webSocketInstances[socketInstance];	socket.socket.send (HEAPU8.buffer.slice(ptr, ptr+length));}, SocketRecvLength: function(socketInstance){	var socket = webSocketInstances[socketInstance];	if (socket.messages.length == 0)		return 0;	return socket.messages[0].length;},

 我只說下他的大概運作機理,Unity調用JS連接服務器,服務器返回包之后JS先緩存起來,然后Unity以循環方式調用JS讀取接受到的數據的頭指針,然后根據長度讀取數據塊數據。這種loop方式無疑增大了數據報的延遲,并且使用起來也很不方便!

注意:我的那種方式也要在C#中緩沖包數據,SendMessage函數回調是在另一個線程中,不能改變主線程Transform等組件的值。
服務器不限制語言,只要是符合Websocket規范的就可以接受發送數據。C#的參見: https://github.com/sta/websocket-sharp
!??!DEMO全源碼:http://www.49028c.com/yinlong1991/p/5090289.html ?。?!
 
結束語
 
大家還有什么不懂的地方盡管問我。
最后,祝大家新年快樂,2016 找到漂釀女盆友~
 
  

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99免视看9| 日韩精品欧美激情| 欧美成人合集magnet| 精品国产欧美一区二区三区成人| 日韩中文字幕精品视频| 亚洲欧美中文日韩在线v日本| 精品成人69xx.xyz| 国产精品久久久久一区二区| 国产精品美女午夜av| 久热爱精品视频线路一| 国产精品成熟老女人| 国产手机视频精品| 中文字幕不卡在线视频极品| 日韩高清电影好看的电视剧电影| 狠狠躁天天躁日日躁欧美| 成人精品一区二区三区电影免费| 7777免费精品视频| 欧美一区第一页| 欧美大片欧美激情性色a∨久久| 国产精品老女人视频| 国产精品成人va在线观看| 92国产精品视频| 欧美日韩在线视频观看| www.亚洲一区| 国产欧美日韩专区发布| 亚洲男人av电影| 久久久久久久香蕉网| 欧美精品国产精品日韩精品| 亚洲在线免费观看| 欧美激情一级二级| 欧美极品在线视频| 日韩亚洲精品电影| 2019日本中文字幕| 国内精品久久久久久中文字幕| 国产精品视频久久| 国产精品久久久一区| 亚洲品质视频自拍网| 亚洲精品狠狠操| 日韩有码片在线观看| 日韩视频―中文字幕| 亚洲色图18p| 欧美日韩国产麻豆| 久久久国产在线视频| 欧美性jizz18性欧美| 亚洲视屏在线播放| 国产亚洲aⅴaaaaaa毛片| 亚洲欧美精品伊人久久| 国产婷婷97碰碰久久人人蜜臀| 国产精品自产拍在线观| 亚洲白拍色综合图区| 日韩乱码在线视频| 中文字幕日韩精品在线| 久久影视电视剧免费网站清宫辞电视| 国产97免费视| 欧美一级淫片aaaaaaa视频| 国产精品第8页| 97婷婷涩涩精品一区| 国产精品video| 欧美大片在线看免费观看| 中文字幕综合在线| 国产一区二区三区四区福利| 欧美日韩国产色| 亚洲久久久久久久久久久| 怡红院精品视频| 精品亚洲一区二区三区在线观看| 九九精品在线播放| 国产成人精品一区二区三区| 91精品视频在线播放| 日本成人黄色片| 欧美午夜精品伦理| 欧美激情一区二区久久久| 欧美激情女人20p| 国产91精品青草社区| 国产精品美女www爽爽爽视频| 国产一区二区三区毛片| 九九热精品视频| 国产日韩专区在线| 久久69精品久久久久久国产越南| 国产在线视频一区| 日韩黄色av网站| 欧美亚洲国产视频小说| 欧美在线激情视频| 久久不射电影网| 国产精品海角社区在线观看| 中文字幕亚洲综合久久| 日韩中文字幕在线免费观看| 91在线视频成人| 成人午夜一级二级三级| 亚洲第一网中文字幕| 国产午夜精品久久久| 日本亚洲精品在线观看| 精品国偷自产在线视频| 亚洲精品www| 伊人伊成久久人综合网站| 欧美黑人xxxx| 亚洲欧美在线磁力| 成人精品视频99在线观看免费| 久久久在线观看| 91理论片午午论夜理片久久| 国产午夜精品久久久| 美女扒开尿口让男人操亚洲视频网站| 最新国产精品拍自在线播放| 精品国产自在精品国产浪潮| xvideos国产精品| 久久久久国产精品免费| 777午夜精品福利在线观看| 55夜色66夜色国产精品视频| 国产91久久婷婷一区二区| 亚洲国产中文字幕久久网| 久热爱精品视频线路一| 亚洲直播在线一区| 亚洲第一页中文字幕| 精品久久久一区| 亚洲精品美女久久久| 91精品视频网站| 日韩中文在线观看| 欧美日韩中文字幕| 欧美日韩性视频| 51ⅴ精品国产91久久久久久| 激情成人中文字幕| 欧美日韩福利视频| 国产亚洲激情视频在线| 久久久久久久久久婷婷| 久久69精品久久久久久国产越南| 国产精品一区二区在线| 欧洲成人免费视频| 久久免费视频在线| 中文字幕亚洲字幕| 欧美成年人视频网站欧美| 欧美电影免费看| 久久精品国亚洲| 欧美激情乱人伦一区| 国产精品午夜视频| 亚洲三级免费看| 中文字幕日韩精品在线| 欧美有码在线视频| 国产伦精品免费视频| 欧美日韩一区二区免费视频| 成人妇女免费播放久久久| 欧洲成人免费视频| 在线播放国产一区中文字幕剧情欧美| 色综合视频网站| 久久久综合免费视频| 久久影院资源网| 色婷婷综合成人| 成人亚洲综合色就1024| 色噜噜狠狠狠综合曰曰曰| 久久精品久久久久久国产 免费| 97人人做人人爱| 成人网欧美在线视频| 国内精品视频在线| www.亚洲成人| 97av在线播放| www.国产精品一二区| 日韩精品极品毛片系列视频| 日韩av免费看| 深夜精品寂寞黄网站在线观看| 精品高清一区二区三区| 欧美另类暴力丝袜| 精品亚洲一区二区三区在线播放| 91国内精品久久| 久久国产精品视频| 亚洲福利在线视频| 欧美日本在线视频中文字字幕|