locked
ASP.Net SirnalR custom url processing RRS feed

  • Question

  • User1608824176 posted

    Hello!

    I've searhed Inet for couple hours, but had not found info about my problem.

    So, i have my SignalR application, and i have main page "index.html".

    I want to use iframe src="www..../parameter1/parameter2". In that case browser should open "index.html" and i should be able to take information about both parametres values on server.

    How can i do it? I found some info about routing, mapowinpath, but it's not worked for me, or i did it wrong :)

    Thank you!

    Saturday, March 18, 2017 6:00 AM

All replies

  • User-707554951 posted

    Hi qpIlIpp,

    From your description, I am not understand your problem.

    Would you please explains us on the following points:

    what is "www..../parameter1/parameter2" ?

    take information about both parametres values on server.

    Why you need to take information about both parametres values?

    Why you set src value to index.html address directly.

    Best regards

    Cathy

    Monday, March 20, 2017 10:45 AM
  • User1608824176 posted

    I did what i want, but it's some.. mm.. hacking =)

    Look:

    I have several count of named data, let it be "Data", also i have users, "User".

    So i want to use url like "www.site.com/User/Data". Of course, i haven't this physical page, so i should process that request dynamicly.

    Also i have my "index.html", which contains info abut processing "data" and "user", that page uses SignalR.

    So i want to use page "index.html" from all sites like "{user}/{data}", it's routing, as i understood. And i want to call callback on the index.html like "alert(user+data)", so i need to get that information from the server.

    Here's the problem: how can i use routing with SignalR correctly and how can i remember "Data" and "User" to send it via some Hub function?

    I created next classes:

    class MyRouteHandler : IRouteHandler
    	{
    		public MyRouteHandler(string virtualPath)
    		{
    			this.VirtualPath = virtualPath;
    		}
    
    		public string VirtualPath { get; private set; }
    
    		public IHttpHandler GetHttpHandler(RequestContext requestContext)
    		{
    			return new MultontHttpHandler(requestContext);
    		}
    	}
    
    class MultontHttpHandler : IHttpHandler
    	{
    		internal static object GetInstanceField(Type type, object instance, string fieldName)
    		{
    			BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
    				| BindingFlags.Static;
    			var field = type.GetProperty(fieldName, bindFlags);
    			return field.GetValue(instance);
    		}
    		public static long ClientToken(HttpContext httpContext)
    		{
    			var val = GetInstanceField(typeof(HttpContext), httpContext, "ClientIdentityToken");
    			IntPtr ip = (IntPtr)val;
    			return ip.ToInt64();
    		}
    
    		private static Dictionary<long, Tuple<string, string>> clients = new Dictionary<long, Tuple<string, string>>();
    
    		public static Tuple<string, string> getClientInfo(HttpContext httpContext)
    		{
    			return getClientInfo(ClientToken(httpContext));
    		}
    		public static Tuple<string, string> getClientInfo(long ind)
    		{
    			if (clients.ContainsKey(ind))
    			{
    				return clients[ind];
    			}
    			return null;
    		}
    
    		public static void setClientInfo(long ind, Tuple<string, string> value)
    		{
    			if (clients.ContainsKey(ind))
    			{
    				clients.Remove(ind);
    			}
    			clients.Add(ind, value);
    		}
    		public static void removeConnection(HttpContext httpContext)
    		{
    			var K = ClientToken(httpContext);
    			if (clients.ContainsKey(K))
    				clients.Remove(K);
    
    		}
    		public MultontHttpHandler(RequestContext requestContext)
    		{
    			context = requestContext;
    		}
    		public RequestContext context { get; set; }
    		public bool IsReusable
    		{
    			get
    			{
    				return true;
    			}
    		}
    
    		public void ProcessRequest(HttpContext httpContext)
    		{
    			var userId = context.RouteData.GetRequiredString("user");
    			var ontologyId = context.RouteData.GetRequiredString("ontology");
    			setClientInfo(ClientToken(httpContext), new Tuple<string, string>(userId, ontologyId));
    			var path = System.Web.HttpContext.Current.Server.MapPath("~/index.html");
    			var html = File.ReadAllText(path);
    			httpContext.Response.Write(html);
    		}
    	}

    and use it here:

    public class Startup
    	{
    		public void Configuration(IAppBuilder app)
    		{
    			RouteTable.Routes.Add(new Route("{user}/{ontology}", new MyRouteHandler("~/index.html")));

    It's all ok, but it's VERY bad that i should use reflection to differ users like that:

    var i = MultontHttpHandler.getClientInfo(System.Web.HttpContext.Current)

    I am using connection id to determine users:

    private string GetClientId()
    		{
    			string clientId = "";
    			if (Context.QueryString["clientId"] != null)
    			{
    				clientId = this.Context.QueryString["clientId"];
    			}
    			if (string.IsNullOrEmpty(clientId.Trim()))
    			{
    				clientId = Context.ConnectionId;
    			}
    
    			return clientId;
    		}

    The problem with it that it's not 1:1 relation between Context.QueryString["clientId"] : HttpContext.ClientIdentityToken, it's N:1. And i don't want to use hacks with reflection to get some field info.

    If u're still not understand what am i doing, look at multont.azurewebsites.net/user1/ont1 , open same page in different tabs, add node (right click in middle of the screen, click first menu_item, enter name), the node should create on both tabs. When u go to multont.azurewebsites.net/user1/ont2 , it will be different ontology, (u can also add node ant it will sync) but both of that pages is "index.html"

    I hope now it's clear, what am i want :)

    Sorry for my English, i can repeat it in Russian ^^

    Monday, March 20, 2017 2:08 PM