我正在创建带有集成SignalR集线器的WebApi服务器。为简单起见,我使用的是在List
上运行的Controller。
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
public static List<string> Source { get; set; } = new List<string>();
public static int counter = 0;
private IHubContext<ValuesHub, IValuesClient> hubContext;
public ValuesController(IHubContext<ValuesHub, IValuesClient> hub)
{
Source.Add("bla" + counter);
counter++;
Source.Add("bla" + counter);
counter++;
this.hubContext = hub;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return Source;
}
// GET api/values/x
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return Source[id];
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
Source.Add(value);
}
// PUT api/values/x
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
Source[id] = value;
}
// DELETE api/values/x
[HttpDelete("{id}")]
public void Delete(int id)
{
var item = Source[id];
Source.Remove(item);
Console.WriteLine("Outgoing message!");
hubContext.Clients.All.ReceiveMessage("Message incoming", "Blaaaaa");
}
}
}
“我的中心”还没有执行任何特殊操作:
public interface IValuesClient
{
Task ReceiveMessage(string value, string message);
Task ReceiveMessage(string message);
}
public class ValuesHub : Hub<IValuesClient>
{
// private static ValuesController ctrl = Glo
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "Users");
Console.WriteLine("Client connected - Client-Id: {0}", Context.ConnectionId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Users");
Console.WriteLine("Client disconnected - Client-Id: {0}", Context.ConnectionId);
Console.WriteLine("Disconnection due to: {0}", exception);
await base.OnDisconnectedAsync(exception);
}
public async Task MessageToAll(string user, string message)
{
Console.WriteLine("SendMessage - User: {0} - Message: {1}", user, message);
await Clients.All.ReceiveMessage(user, message);
}
public async Task MessageToCaller(string message)
{
Console.WriteLine("SendMessageToCaller: {0}", message);
await Clients.Caller.ReceiveMessage(message);
}
}
}
为了简单起见,我将不详细说明为什么要实现此目的,但是我希望服务器在检测到断开连接后等待一定时间,然后删除相应的值。假设我只想删除Source
列表中的第一个元素。
我如何从OnDisconnectedAsync
函数内部访问相应的控制器功能?
我想到的一个想法是在集线器内部创建一个HttpClient
,并通过调用e使集线器在此处充当客户端。 G。 DELETE: http://localhost:5000/api/values/0
。不过,我必须承认这听起来像是一种非常可怕的方法。
答案 0 :(得分:1)
因此,如果我了解您的问题是您要从集线器访问控制器上的方法,则该问题是否存在?
如果是这种情况-在我看来,您有一个基本的设计缺陷。我将创建一个处理您控制器正在执行的所有操作的服务,然后将该服务直接注入到集线器中。然后,您可以直接在替代中心中使用该服务,并在列表上进行操作。如果不清楚,我可以举个例子。
public class ValuesHub : Hub<IValuesClient>
{
IListService _listService;
public ValuesHub (IListService listService)
{
_listService = listService;
}
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "Users");
Console.WriteLine("Client connected - Client-Id: {0}", Context.ConnectionId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Users");
Console.WriteLine("Client disconnected - Client-Id: {0}", Context.ConnectionId);
Console.WriteLine("Disconnection due to: {0}", exception);
//Call your methods here.
_listService.RemoveFirstElement();
await base.OnDisconnectedAsync(exception);
}
public async Task MessageToAll(string user, string message)
{
Console.WriteLine("SendMessage - User: {0} - Message: {1}", user, message);
await Clients.All.ReceiveMessage(user, message);
}
public async Task MessageToCaller(string message)
{
Console.WriteLine("SendMessageToCaller: {0}", message);
await Clients.Caller.ReceiveMessage(message);
}
}
}
这就是您的中心-请参见下面的服务示例
public class ListService : IListService
{
public void RemoveFirstElement()
{
//Delete Your Element here
}
}
public interface IListService
{
void RemoveFirstElement();
}
然后是您的startup.cs
services.AddSingleton<IListService,ListService>();