SignalR原本就是網頁支持的技術,底層應該是用WebSocket的。
但是項目打包成WebGL後,發現無法獲取服務端的告警信息,需要另外研究一下了。
Unity裏面的SignalR是用BestHTTP實現的。
一、搭建服務端
我用控制檯引用程序搭建服務端,先創建控制檯項目,然後加上需要的庫
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Owin;
using Microsoft.Owin.Cors;
namespace SignalRServer
{
class Program
{
static void Main(string[] args)
{
var uri = "http://127.0.0.1:9999";
using (Microsoft.Owin.Hosting.WebApp.Start<Startup>(uri))
{
Console.WriteLine(string.Format("Server stared on {0}", uri));
Console.ReadLine();
}
}
}
class Startup
{
static Hub hub;
public void Configuration(IAppBuilder app)
{
//app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
//var configuration = new HubConfiguration();
//configuration.EnableDetailedErrors = true;
//app.MapSignalR("/signalr", configuration);
//hub = new MyHub();
app.Map("/realtime", map =>
{
map.UseCors(CorsOptions.AllowAll);
var config = new HubConfiguration()
{
EnableJSONP = true,
//EnableJavaScriptProxies = false
};
#if DEBUG
config.EnableDetailedErrors = true;
#endif
map.RunSignalR(config);
});
}
}
public class MyHub : Hub
{
public override Task OnConnected()
{
Console.WriteLine("有客戶端連接");
return base.OnConnected();
}
//服務端的方法,客戶端可以去調用
public void Send(string name, string message)
{
Console.WriteLine("[{0}]Send:{1}", name, message);
//string name = "BG";
//調用客戶端的方法sendMessage(string s1,string s2);
Clients.All.AddMessage(name, message);
}
}
}
二、Html客戶端
參考《ASP.NET SignalR編程實戰》,書本代碼地址:https://resources.oreilly.com/examples/9780735683884-files/
參考代碼:https://www.haolizi.net/example/tags_SignalR_1.html
<!DOCTYPE html>
<html>
<head>
<title>SignalR Simple Chat</title>
<style type="text/css">
.container {
background-color: #99CCFF;
border: thick solid #808080;
padding: 20px;
margin: 20px;
}
</style>
</head>
<body>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<ul id="discussion"></ul>
</div>
<!--Script references. -->
<!--Reference the jQuery library. -->
<script src="Scripts/jquery-1.6.4.min.js"></script>
<!--Reference the SignalR library. -->
<script src="Scripts/jquery.signalR-2.0.3.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="http://127.0.0.1:9999/realtime/hubs"></script>
<!--Add script to update the page and send messages.-->
<script type="text/javascript">
$(function () {
//Set the hubs URL for the connection
//$.connection.hub.url = "http://localhost:8080/signalr";
$.connection.hub.url = "http://127.0.0.1:9999/realtime";
// Declare a proxy to reference the hub.
var chat = $.connection.myHub;
// Create a function that the hub can call to broadcast messages.
chat.client.addMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
</body>
</html>
在哪裏設置url裏面花了些時間,網上找的例子都是不需要設置url的,是直接通過aps.net啓動網頁,然後使用的。
而這個是單獨的html頁面啓動的,也不用放到iis裏面,就是一個獨立的html客戶端。
三、Unity客戶端
我用的BestHttp是1.9.9 (2016.02.16)。
3年多了啊,應該更新一下了。
Unity代碼
using System;
using UnityEngine;
using BestHTTP.SignalR;
using BestHTTP.SignalR.Hubs;
using BestHTTP.SignalR.Messages;
using BestHTTP.SignalR.JsonEncoders;
using BestHTTP.Examples;
using UnityEngine.UI;
using BestHTTP;
public class MyHubSample : MonoBehaviour
{
public InputField InputFieldUrl;
public InputField InputFieldName;
public InputField InputFieldMessage;
public Text TextReceived;
public string URI = "http://127.0.0.1:9999/realtime";
/// <summary>
/// The SignalR connection instance
/// </summary>
Connection signalRConnection;
private MyHub myHub;
void Start()
{
//StartHub();
}
void OnDestroy()
{
StopHub();
}
public void StartHub()
{
HTTPManager.Setup();
HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.All;
Debug.Log("HTTPManager.Logger.Level:" + HTTPManager.Logger.Level);
TextReceived.text = "";
if (InputFieldUrl)
{
URI = InputFieldUrl.text;
}
myHub = new MyHub();
myHub.received += (msg) => { TextReceived.text += msg + "\n"; };
// Create the SignalR connection, passing all the three hubs to it
//signalRConnection = new Connection(URI, demoHub, typedDemoHub, vbDemoHub);
signalRConnection = new Connection(new Uri(URI), myHub);
// Switch from the default encoder to the LitJson Encoder becouse it can handle the complex types too.
signalRConnection.JsonEncoder = new LitJsonEncoder();
// Call the demo functions when we successfully connect to the server
signalRConnection.OnConnected += (connection) =>
{
Debug.Log("signalRConnection.OnConnected");
//myHub.Send("Unity", "Hello");
Send();
};
// Start opening the signalR connection
signalRConnection.Open();
}
public void StopHub()
{
// Close the connection when we are closing this sample
if(signalRConnection!=null)
signalRConnection.Close();
}
public void Send()
{
string user = "Unity";
if (InputFieldName)
{
user = InputFieldName.text;
}
string messag = "Hello";
if (InputFieldMessage)
{
messag = InputFieldMessage.text;
}
myHub.Send(user, messag);
}
}
class MyHub : Hub
{
public event Action<string> received;
public MyHub()
: base("myHub")
{
// Setup server-called functions
base.On("AddMessage", AddMessage);
}
private void AddMessage(Hub hub, MethodCallMessage methodCall)
{
string typedEchoClientResult = string.Format("{0} #{1} triggered!", methodCall.Arguments[0], methodCall.Arguments[1]);
string msg = methodCall.Arguments[1]+"";
Debug.Log("MyHub.AddMessage:" + typedEchoClientResult);
if (received != null)
{
received(msg);
}
}
public void Send(string name, string msg)
{
Debug.Log("MyHub.Send:" + name + "," + msg);
base.Call("Send", name, msg);
}
}
結果來說,exe打包是沒問題的,webgl打包出錯了。
發送的ws以及httprequest的地址有問題,上面的地址ws和GET的地址,仔細觀察會發現有%252F,這樣的其實是/。
/ => %2F => %252F。
%25是 %,會發現地址裏面很多%25,其實就是多轉換了一次。
BestHTTP_WebSocket.jslib修改:
BestHTTP_WebRequest.jslib修改:
文件位置
然後在打包就可以了。
搞了一整天,弄來弄起,結果發現BestHttp插件本身有問題。。。。。。。,難道16年時需要這麼寫的,而現在不用了,變成多此一舉了。。。。
估計升級一下插件的版本可能也可以解決這個問題,明天有空試試。
哎,一天下來,大體明白了SinalR的協商過程。一點點收穫。
-----------------------------------------------------------------------------------------------------------------------
在淘寶上買了個1.12.5的版本,1.12.5 (2019.09.03),2塊錢.....
看代碼,確實把我昨天改的那部分改好了。
打包webgl,測試,沒問題。
果然應該不斷與時俱進的。
出了問題,除了考慮自己解決外,要考慮插件有沒有新版本。