自托管websocket服务多OperationContract?

时间:2014-12-03 16:22:04

标签: websocket

首先,对不起我的英语......

我有一个问题,我搜索过但我没有找到任何答案。

我在https://stackoverflow.com/questions/....

找到了答案代码

此代码正常工作..

WebSocket服务和服务器:

// Self-hosted Server start at http://localhost:8080/hello
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;

namespace WebSocketsServer
{
    class Program
    {
        static void Main(string[] args)
        {

            Uri baseAddress = new Uri("http://localhost:8080/hello");

            // Create the ServiceHost.
            using(ServiceHost host = new ServiceHost(typeof(WebSocketsServer), baseAddress))
            {
                // Enable metadata publishing.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);

                CustomBinding binding = new CustomBinding();
                binding.Elements.Add(new ByteStreamMessageEncodingBindingElement());
                HttpTransportBindingElement transport = new HttpTransportBindingElement();
                //transport.WebSocketSettings = new WebSocketTransportSettings();
                transport.WebSocketSettings.TransportUsage = WebSocketTransportUsage.Always;
                transport.WebSocketSettings.CreateNotificationOnConnection = true;
                binding.Elements.Add(transport);

                host.AddServiceEndpoint(typeof(IWebSocketsServer), binding, "");

                host.Open();

                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();

                // Close the ServiceHost.
                host.Close();
            }
        }
    }

    [ServiceContract(CallbackContract = typeof(IProgressContext))]
    public interface IWebSocketsServer
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SendMessageToServer(Message msg);
    }

    [ServiceContract]
    interface IProgressContext
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void ReportProgress(Message msg);
    }

    public class WebSocketsServer: IWebSocketsServer
    {
        public void SendMessageToServer(Message msg)
        {
            var callback = OperationContext.Current.GetCallbackChannel<IProgressContext>();
            if(msg.IsEmpty || ((IChannel)callback).State != CommunicationState.Opened)
            {
                return;
            }

            byte[] body = msg.GetBody<byte[]>();
            string msgTextFromClient = Encoding.UTF8.GetString(body);

            string msgTextToClient = string.Format(
                "Got message {0} at {1}",
                msgTextFromClient,
                DateTime.Now.ToLongTimeString());

            callback.ReportProgress(CreateMessage(msgTextToClient));
        }

        private Message CreateMessage(string msgText)
        {
            Message msg = ByteStreamMessage.CreateMessage(
                new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgText)));

            msg.Properties["WebSocketMessageProperty"] =
                new WebSocketMessageProperty
                {
                    MessageType = WebSocketMessageType.Text
                };

            return msg;
        }
    }
}

和客户端Html页面:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>WebSocket Chat</title>
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.js"></script>
<script type="text/javascript">
    var ws;
    $().ready(function ()
    {
        $("#btnConnect").click(function ()
        {
            $("#spanStatus").text("connecting");

            ws = new WebSocket("ws://localhost:8080/hello");

            ws.onopen = function ()
            {
                $("#spanStatus").text("connected");
            };
            ws.onmessage = function (evt)
            {
                $("#spanStatus").text(evt.data);
            };
            ws.onerror = function (evt)
            {
                $("#spanStatus").text(evt.message);
            };
            ws.onclose = function ()
            {
                $("#spanStatus").text("disconnected");
            };
        });
        $("#btnSend").click(function ()
        {
            if (ws.readyState == WebSocket.OPEN)
            {
                var res = ws.send($("#textInput").val());
            }
            else
            {
                $("#spanStatus").text("Connection is closed");
            }
        });
        $("#btnDisconnect").click(function ()
        {
            ws.close();
        });
    });
</script>
</head>
<body>
<input type="button" value="Connect" id="btnConnect" />
<input type="button" value="Disconnect" id="btnDisconnect" /><br />
<input type="text" id="textInput" />
<input type="button" value="Send" id="btnSend" /><br />
<span id="spanStatus">(display)</span>
</body>
</html>

这工作得很好!..但是...... :)

IWebSocketsServer有一个方法和Action =&#34; *&#34; OperationContract属性中的参数。

[ServiceContract(CallbackContract = typeof(IProgressContext))]
public interface IWebSocketsServer
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void SendMessageToServer(Message msg);
}

当我删除Action =&#34; *&#34;参数。

但是我想添加像SendMessageToServer这样的新方法。

[ServiceContract(CallbackContract = typeof(IProgressContext))]
public interface IWebSocketsServer
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void SendMessageToServer(Message msg);

    [OperationContract(IsOneWay = true, Action = "*")]
    void DifferentMethod(string msg);
}

但是当自托管服务器启动时,此代码抛出错误&#34;一个ServiceContract有一个操作,其行为为&#34; &#34;。 ServiceContract最多可以有一个操作=&#34; &#34;。&#34;

我尝试更改动作参数的值,如&#34;发送&#34;,&#34;测试&#34;。服务器启动没有问题。 但是客户没有连接到&#34; ws:// localhost:8080 / hello&#34; ...

我想调用像

这样的方法
            ws = new WebSocket("ws://localhost:8080/Send");

            ws = new WebSocket("ws://localhost:8080/Test");

我需要帮助。

1 个答案:

答案 0 :(得分:1)

您不能拥有两个指向“*”的操作合约。这会产生您收到的错误消息。 看到: https://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.action(v=vs.110).aspx

如果您在这些端点上有服务,那么您指定的两个调用将为每个端点创建一个WebSocket连接。

ws = new WebSocket("ws://localhost:8080/Send");
ws = new WebSocket("ws://localhost:8080/Test");

我认为您需要的是WebSocket连接,然后使用ws.Send(message)向WebSocket服务器发送消息。如果您使用子协议来获取消息,则可以获得所需的灵活性。

希望能帮助您继续使用WebSockets。