Beispiel #1
0
        static ChannelAuth CreateChannel(
            string appId, string channelId,
            string regionId, string endpoint, string accessKeyId,
            string accessKeySecret)
        {
            try
            {
                IClientProfile profile = DefaultProfile.GetProfile(
                    regionId, accessKeyId, accessKeySecret);
                IAcsClient client = new DefaultAcsClient(profile);

                CreateChannelRequest request = new CreateChannelRequest();
                request.AppId     = appId;
                request.ChannelId = channelId;

                // Strongly recomment to set the RTC endpoint,
                // because the exception is not the "right" one if not set.
                // For example, if access-key-id is invalid:
                //      1. if endpoint is set, exception is InvalidAccessKeyId.NotFound
                //      2. if endpoint isn't set, exception is SDK.InvalidRegionId
                // that's caused by query endpoint failed.
                // @remark SDk will cache endpoints, however it will query endpoint for the first
                //      time, so it's good for performance to set the endpoint.
                DefaultProfile.AddEndpoint(regionId, regionId, request.Product, endpoint);

                // Use HTTP, x3 times faster than HTTPS.
                request.Protocol = Aliyun.Acs.Core.Http.ProtocolType.HTTP;

                CreateChannelResponse response = client.GetAcsResponse(request);

                ChannelAuth auth = new ChannelAuth();
                auth.AppId      = appId;
                auth.ChannelId  = channelId;
                auth.Nonce      = response.Nonce;
                auth.Timestamp  = (Int64)response.Timestamp;
                auth.ChannelKey = response.ChannelKey;
                auth.Recovered  = false;
                auth.RequestId  = response.RequestId;

                return(auth);
            }
            catch (Exception ex)
            {
                return(RecoverForError(ex, appId, channelId));
            }
        }
Beispiel #2
0
        static ChannelAuth RecoverForError(Exception ex, string appId, string channelId)
        {
            bool   fatal     = false;
            string requestId = "";

            ClientException cex = ex as ClientException;

            if (cex != null && cex.ErrorCode != null)
            {
                requestId = cex.RequestId;
                string code = cex.ErrorCode;
                if (code == "IllegalOperationApp")
                {
                    fatal = true;
                }
                else if (code.StartsWith("InvalidAccessKeyId", StringComparison.Ordinal))
                {
                    fatal = true;
                }
                else if (code == "SignatureDoesNotMatch")
                {
                    fatal = true;
                }
            }

            if (fatal)
            {
                throw ex;
            }

            string recovered = "RCV-" + Guid.NewGuid().ToString();

            System.Console.WriteLine("Recover from {0}, recovered={1}", ex.ToString(), recovered);

            ChannelAuth auth = new ChannelAuth();

            auth.AppId      = appId;
            auth.ChannelId  = channelId;
            auth.Nonce      = recovered;
            auth.Timestamp  = 0;
            auth.ChannelKey = recovered;
            auth.Recovered  = true;

            return(auth);
        }
Beispiel #3
0
        static void HandleRequest(HttpListenerContext context, string appid, string accessKeyId, string accessKeySecret, string gslb, string regionId, string endpoint)
        {
            if (context.Request.Headers.Get("Origin") != "")
            {
                context.Response.Headers.Set("Access-Control-Allow-Origin", "*");
                context.Response.Headers.Set("Access-Control-Allow-Methods", "GET,POST,HEAD,PUT,DELETE,OPTIONS");
                context.Response.Headers.Set("Access-Control-Expose-Headers", "Server,Range,Content-Length,Content-Range");
                context.Response.Headers.Set("Access-Control-Allow-Headers", "Origin,Range,Accept-Encoding,Referer,Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type");
            }

            if (context.Request.HttpMethod == "OPTIONS")
            {
                responseWrite(context, HttpStatusCode.OK, "");
                return;
            }

            string url = context.Request.RawUrl;

            System.Console.WriteLine(String.Format("URL={0}", url));
            if (!url.StartsWith("/app/v1/login", StringComparison.Ordinal))
            {
                responseWrite(context, HttpStatusCode.NotFound, String.Format("Invalid url {0}", url));
                return;
            }

            string channelId  = context.Request.QueryString.Get("room");
            string user       = context.Request.QueryString.Get("user");
            string channelUrl = string.Format("{0}/{1}", appid, channelId);

            System.Console.WriteLine(String.Format("Request channelId={0}, user={1}, appid={2}", channelId, user, appid));

            try
            {
                DateTime starttime = DateTime.Now;

                ChannelAuth auth = null;
                using (Mutex locker = new Mutex())
                {
                    locker.WaitOne();

                    if (channels.ContainsKey(channelUrl))
                    {
                        auth = channels[channelUrl];
                    }
                    else
                    {
                        auth = CreateChannel(appid, channelId, regionId, endpoint, accessKeyId, accessKeySecret);

                        // If recovered from error, we should never cache it,
                        // and we should try to request again next time.
                        if (!auth.Recovered)
                        {
                            channels[channelUrl] = auth;
                        }

                        System.Console.WriteLine(String.Format(
                                                     "CreateChannel requestId={4}, cost={6}ms, channelId={0}, nonce={1}, timestamp={2}, channelKey={3}, recovered={5}",
                                                     channelId, auth.Nonce, auth.Timestamp, auth.ChannelKey, auth.RequestId, auth.Recovered, DateTime.Now.Subtract(starttime).Milliseconds));
                    }
                }

                string userId = CreateUserId();
                string token  = CreateToken(channelId, auth.ChannelKey, appid, userId,
                                            auth.Nonce, auth.Timestamp);
                string username = String.Format(
                    "{0}?appid={1}&channel={2}&nonce={3}&timestamp={4}",
                    userId, appid, channelId, auth.Nonce, auth.Timestamp);
                System.Console.WriteLine("Sign cost={4}ms, user={0}, userId={1}, token={2}, channelKey={3}",
                                         user, userId, token, auth.ChannelKey, DateTime.Now.Subtract(starttime).Milliseconds);

                JObject rturn = new JObject();
                rturn.Add("username", username);
                rturn.Add("password", token);

                JArray rgslbs = new JArray();
                rgslbs.Add(gslb);

                JObject rresponse = new JObject();
                rresponse.Add("appid", appid);
                rresponse.Add("userid", userId);
                rresponse.Add("gslb", rgslbs);
                rresponse.Add("token", token);
                rresponse.Add("nonce", auth.Nonce);
                rresponse.Add("timestamp", auth.Timestamp);
                rresponse.Add("turn", rturn);

                JObject ro = new JObject();
                ro.Add("code", 0);
                ro.Add("data", rresponse);

                responseWrite(context, HttpStatusCode.OK, ro.ToString());
            }
            catch (Exception ex)
            {
                responseWrite(context, HttpStatusCode.InternalServerError, ex.Message);
                System.Console.WriteLine(ex.ToString());
            }
        }