Publish message to channel from MVC Action

49 views
Skip to first unread message

Austin

unread,
Apr 5, 2011, 3:51:31 PM4/5/11
to aspComet
I'm wondering the simplest way to publish a message to a channel when
a particular ASP.NET MVC Action gets invoked. For example, I have a
Create action on my ProjectsController and I'd like to publish a
message to the channel that that project belongs to when a new project
is created. This MVC action could be called from a regular HTTP
request. Is that a problem to mix comet messages going through
aspComet with standard HTTP requests?

Symon Rottem

unread,
Apr 6, 2011, 8:47:53 AM4/6/11
to aspc...@googlegroups.com
Oh, an no, it's fine to publish from an Action - it's been working for me at least.

Cheers,

Symon.

Symon Rottem

unread,
Apr 6, 2011, 8:46:34 AM4/6/11
to aspc...@googlegroups.com
If you've registered ASPComet into an IOC container and are using the same container for your MVC controllers then if you expose a setter or constructor for an IClientRepository the client repository should be injected into your controller and you can publish messages using that.

For example:


/// <summary>
/// A controller class.
/// </summary>
public class MyController
{
/// <summary>
/// Get/sets the ASPComet client respository.
/// </summary>
public IClientRepository AspComet { get; set; }

/// <summary>
/// An action method.
/// </summary>
public void MyAction()
{
var message = new Message();
message.SetData("message", "data to publish");

PublishCometMessage("channel_to_publish_to", message);
}

/// <summary>
/// Publishes the message.
/// </summary>
/// <param name="channel">The channel to publish to.</param>
/// <param name="message">The message to publish.</param>
private void PublishCometMessage(string channel, Message message)
{
message.channel = channel;

foreach (var subscriber in AspComet.WhereSubscribedTo(channel))
{
subscriber.Enqueue(message);
subscriber.FlushQueue();
}
}
}


Hope that helps.

Cheers,

Symon.
On Tue, Apr 5, 2011 at 9:51 PM, Austin <austi...@gmail.com> wrote:

Austin

unread,
Apr 7, 2011, 3:51:28 PM4/7/11
to aspComet
Symon,

Thanks for the code sample. I see how to publish a message to a
channel in a controller now. I guess the problem is primarily my lack
of knowledge about IoC. I'm trying to use Autofac (since that is what
the example AspComet uses) in my MVC3 project and I'm not sure how to
make Autofac feed the IClientRepository to my controller. I've got the
IClientRepository getter/setter in my controller and here is what my
Application_Start looks like:

private static IContainer container;

protected void Application_Start()
{
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

var builder = new ContainerBuilder();

// Let AspComet put its registrations into the container
foreach (ServiceMetadata metadata in
ServiceMetadata.GetMinimumSet())
{
if (metadata.IsPerRequest)

builder.RegisterType(metadata.ActualType).As(metadata.ServiceType);
else

builder.RegisterType(metadata.ActualType).As(metadata.ServiceType).SingleInstance();
}

builder.RegisterControllers(typeof(MvcApplication).Assembly);

//// Add our own stuff to the container

builder.RegisterType<AuthenticatedClientFactory>().As<IClientFactory>().SingleInstance();
builder.RegisterType<HandshakeAuthenticator>().SingleInstance();
builder.RegisterType<SubscriptionChecker>().SingleInstance();

container = builder.Build();

DependencyResolver.SetResolver(new
AutofacDependencyResolver(container));
}

Am I missing something? It seems like I need something to tell the IoC
to hookup the IClientRepository to the controller...

Thanks,
Austin
> Symon Rottemhttp://blog.symbiotic-development.com

Symon Rottem

unread,
Apr 7, 2011, 5:23:10 PM4/7/11
to aspc...@googlegroups.com
The container should automatically inject the IClientRepository instance into your controller as long as you have that public setter. 

You've already registered all the ASPComet components and your controllers into the container so the container should inject it for you using dependency injection.  Read up on Autofac and dependency injection for more info on how this works.

Cheers,

Symon.

Austin

unread,
Apr 7, 2011, 5:26:13 PM4/7/11
to aspComet
I passed the IClientRespository into the constructor of the
ProjectsController and now it is receiving the client repository. I
then started working on my client side code and got that submitting
requests, but I'm getting a 404 (Not Found) error for the initial
handshake request:

http://localhost:3493/comet.axd/handshake

The sample chat application works and doesn't give me that error, but
I noticed it is running the application pool in Classic Mode (which I
don't think I can do for an MVC3 application, I need it in Integrated
mode). Could that be making the difference? Can AspComet run in
Integrated mode?

Thanks,
Austin

Austin

unread,
Apr 12, 2011, 7:34:02 AM4/12/11
to aspComet
In case anyone comes across this, I had to add the following lines to
my Web.config in the <system.webServer> section to fix the 404
problem:

<handlers>
<add name="AspComet" path="comet.axd" verb="POST"
type="AspComet.CometHttpHandler, AspComet" resourceType="Unspecified"
preCondition="integratedMode" />
</handlers>

I had the following line in my <system.web><httpHandlers> section:

<add verb="POST" path="comet.axd" validate="false"
type="AspComet.CometHttpHandler, AspComet" />

But it didn't work in my MVC3 project until I added the additional
lines to my <system.webServer>
Reply all
Reply to author
Forward
0 new messages