C# 如何在twitter上引发新事件,以便客户端可以接收事件通知?
我正在使用LINQ to Twitter 4.1.0检索推文,搜索特定的标签,例如#abc。现在,只要有人在我的帐户中使用相同的标签如#abc发推文,我都想得到通知。有人能告诉我怎么做吗?如果您使用的是REST API,您可以执行定期运行的搜索查询,使用C# 如何在twitter上引发新事件,以便客户端可以接收事件通知?,c#,twitter,linq-to-twitter,C#,Twitter,Linq To Twitter,我正在使用LINQ to Twitter 4.1.0检索推文,搜索特定的标签,例如#abc。现在,只要有人在我的帐户中使用相同的标签如#abc发推文,我都想得到通知。有人能告诉我怎么做吗?如果您使用的是REST API,您可以执行定期运行的搜索查询,使用SinceID/MaxID确保您不搜索已经看到的推文。它的工作原理如下: static async Task DoPagedSearchAsync(TwitterContext twitterCtx) { cons
SinceID
/MaxID
确保您不搜索已经看到的推文。它的工作原理如下:
static async Task DoPagedSearchAsync(TwitterContext twitterCtx)
{
const int MaxSearchEntriesToReturn = 100;
string searchTerm = "twitter";
// oldest id you already have for this search term
ulong sinceID = 1;
// used after the first query to track current session
ulong maxID;
var combinedSearchResults = new List<Status>();
List<Status> searchResponse =
await
(from search in twitterCtx.Search
where search.Type == SearchType.Search &&
search.Query == searchTerm &&
search.Count == MaxSearchEntriesToReturn &&
search.SinceID == sinceID
select search.Statuses)
.SingleOrDefaultAsync();
combinedSearchResults.AddRange(searchResponse);
ulong previousMaxID = ulong.MaxValue;
do
{
// one less than the newest id you've just queried
maxID = searchResponse.Min(status => status.StatusID) - 1;
Debug.Assert(maxID < previousMaxID);
previousMaxID = maxID;
searchResponse =
await
(from search in twitterCtx.Search
where search.Type == SearchType.Search &&
search.Query == searchTerm &&
search.Count == MaxSearchEntriesToReturn &&
search.MaxID == maxID &&
search.SinceID == sinceID
select search.Statuses)
.SingleOrDefaultAsync();
combinedSearchResults.AddRange(searchResponse);
} while (searchResponse.Any());
combinedSearchResults.ForEach(tweet =>
Console.WriteLine(
"\n User: {0} ({1})\n Tweet: {2}",
tweet.User.ScreenNameResponse,
tweet.User.UserIDResponse,
tweet.Text));
}
HandleStreamResponse()
是一种处理通知的方法。我的建议是,您使用消息队列或其他方式,以便在您使用的术语趋向于或获得高流量时不会阻塞流。只是要迅速处理信息
如果您喜欢反应式编程,可以这样做:
static async Task DoRxObservableStreamAsync(TwitterContext twitterCtx)
{
Console.WriteLine("\nStreamed Content: \n");
int count = 0;
var cancelTokenSrc = new CancellationTokenSource();
try
{
var observable =
await
(from strm in twitterCtx.Streaming
.WithCancellation(cancelTokenSrc.Token)
where strm.Type == StreamingType.Filter &&
strm.Track == "twitter"
select strm)
.ToObservableAsync();
observable.Subscribe(
async strm =>
{
await HandleStreamResponse(strm);
if (count++ >= 5)
cancelTokenSrc.Cancel();
},
ex => Console.WriteLine(ex.ToString()),
() => Console.WriteLine("Completed"));
}
catch (OperationCanceledException)
{
Console.WriteLine("Stream cancelled.");
}
}
在回调和反应场景中,监控蒸汽是否关闭(例如,操作取消异常
)。然后必须创建一个全新的流实例才能重新启动。如果发生这种情况,请跟踪您看到的最后一个TweetID
,并使用RESTAPI搜索从那时起到新流开始的所有tweet
更新
在每个演示中,都有一个HandleStreamResponse
方法,即async
。您可以下载并逐步了解它的工作原理。本质上,StreamContent
类型有一个EntityType
属性,告诉响应是什么类型。由于源代码中的演示使用不同类型的流,因此switch
语句说明了所有可能的消息类型。但是,在搜索
流的情况下,唯一的响应将是StreamEntityType.Status
,这将简化您的代码,因为您可以消除其他情况。一旦知道类型,您就可以使用实体
属性(如var status=strm.Entity as status
上的as
运算符进行转换,然后查询状态
变量属性以获取所需信息
static async Task<int> HandleStreamResponse(StreamContent strm)
{
switch (strm.EntityType)
{
case StreamEntityType.Control:
var control = strm.Entity as Control;
Console.WriteLine("Control URI: {0}", control.URL);
break;
case StreamEntityType.Delete:
var delete = strm.Entity as Delete;
Console.WriteLine("Delete - User ID: {0}, Status ID: {1}", delete.UserID, delete.StatusID);
break;
case StreamEntityType.DirectMessage:
var dm = strm.Entity as DirectMessage;
Console.WriteLine("Direct Message - Sender: {0}, Text: {1}", dm.Sender, dm.Text);
break;
case StreamEntityType.Disconnect:
var disconnect = strm.Entity as Disconnect;
Console.WriteLine("Disconnect - {0}", disconnect.Reason);
break;
case StreamEntityType.Event:
var evt = strm.Entity as Event;
Console.WriteLine("Event - Event Name: {0}", evt.EventName);
break;
case StreamEntityType.ForUser:
var user = strm.Entity as ForUser;
Console.WriteLine("For User - User ID: {0}, # Friends: {1}", user.UserID, user.Friends.Count);
break;
case StreamEntityType.FriendsList:
var friends = strm.Entity as FriendsList;
Console.WriteLine("Friends List - # Friends: {0}", friends.Friends.Count);
break;
case StreamEntityType.GeoScrub:
var scrub = strm.Entity as GeoScrub;
Console.WriteLine("GeoScrub - User ID: {0}, Up to Status ID: {1}", scrub.UserID, scrub.UpToStatusID);
break;
case StreamEntityType.Limit:
var limit = strm.Entity as Limit;
Console.WriteLine("Limit - Track: {0}", limit.Track);
break;
case StreamEntityType.Stall:
var stall = strm.Entity as Stall;
Console.WriteLine("Stall - Code: {0}, Message: {1}, % Full: {2}", stall.Code, stall.Message, stall.PercentFull);
break;
case StreamEntityType.Status:
var status = strm.Entity as Status;
Console.WriteLine("Status - @{0}: {1}", status.User.ScreenNameResponse, status.Text);
break;
case StreamEntityType.StatusWithheld:
var statusWithheld = strm.Entity as StatusWithheld;
Console.WriteLine("Status Withheld - Status ID: {0}, # Countries: {1}", statusWithheld.StatusID, statusWithheld.WithheldInCountries.Count);
break;
case StreamEntityType.TooManyFollows:
var follows = strm.Entity as TooManyFollows;
Console.WriteLine("Too Many Follows - Message: {0}", follows.Message);
break;
case StreamEntityType.UserWithheld:
var userWithheld = strm.Entity as UserWithheld;
Console.WriteLine("User Withheld - User ID: {0}, # Countries: {1}", userWithheld.UserID, userWithheld.WithheldInCountries.Count);
break;
case StreamEntityType.ParseError:
var unparsedJson = strm.Entity as string;
Console.WriteLine("Parse Error - {0}", unparsedJson);
break;
case StreamEntityType.Unknown:
default:
Console.WriteLine("Unknown - " + strm.Content + "\n");
break;
}
return await Task.FromResult(0);
}
静态异步任务HandleStreamResponse(StreamContent strm)
{
交换机(strm.EntityType)
{
案例StreamEntityType.控件:
var控制=作为控制的标准实体;
WriteLine(“控件URI:{0}”,Control.URL);
打破
案例StreamEntityType。删除:
var delete=strm.Entity作为delete;
WriteLine(“Delete-User-ID:{0},Status-ID:{1}”,Delete.UserID,Delete.StatusID);
打破
案例StreamEntityType.DirectMessage:
var dm=strm.Entity作为DirectMessage;
WriteLine(“直接消息-发送者:{0},文本:{1}”,dm.Sender,dm.Text);
打破
案例StreamEntityType。断开:
var disconnect=将实体作为disconnect;
WriteLine(“Disconnect-{0}”,Disconnect.Reason);
打破
案例StreamEntityType。事件:
var evt=strm.Entity作为事件;
WriteLine(“事件-事件名称:{0}”,evt.EventName);
打破
案例StreamEntityType.ForUser:
var user=strm.Entity作为ForUser;
WriteLine(“对于用户-用户ID:{0},#Friends:{1}”,User.UserID,User.Friends.Count);
打破
案例StreamEntityType.FriendsList:
var friends=strm.Entity作为FriendsList;
WriteLine(“好友列表-#好友:{0}”,Friends.Friends.Count);
打破
案例StreamEntityType.GeoScrub:
var scrub=strm.Entity作为GeoScrub;
WriteLine(“GeoScrub-User ID:{0},状态ID:{1}”,scrub.UserID,scrub.UpToStatusID);
打破
案例StreamEntityType。限制:
var限额=作为限额的标准实体;
WriteLine(“Limit-Track:{0}”,Limit.Track);
打破
案例StreamEntityType.暂停:
var stall=作为stall的strm.实体;
WriteLine(“Stall-Code:{0},Message:{1},%Full:{2}”,Stall.Code,Stall.Message,Stall.PercentFull);
打破
案例StreamEntityType。状态:
var status=作为状态的标准实体;
WriteLine(“Status-@{0}:{1}”,Status.User.screennamesponse,Status.Text);
打破
案例StreamEntityType.StatusInjected:
var StatusDeployed=作为StatusDeployed的标准实体;
WriteLine(“Status dependent-Status ID:{0},#Countries:{1}”、statusdependent.StatusID、statusdependent.WithheldInCountries.Count);
打破
案例StreamEntityType.TooManyFollows:
var follows=strm.Entity作为TooManyFollows;
WriteLine(“Follows太多-消息:{0}”,Follows.Message);
打破
case StreamEntityType.userInjected:
var UserDeployed=strm.Entity作为UserDeployed;
WriteLine(“用户扣留-用户ID:{0},#国家:{1}”,User扣留。UserID,User扣留。WithheldInCountries.Count);
打破
案例StreamEntityType.ParseError:
var unparsedJson=strm.Entity作为字符串;
WriteLine(“解析错误-{0}”,unparsedJson);
打破
案例StreamEntityType。未知:
违约:
Console.WriteLine(“未知-”+strm.Content+“\n”);
打破
}
返回等待任务。FromResult(0);
}
感谢您的回复。
static async Task<int> HandleStreamResponse(StreamContent strm)
{
switch (strm.EntityType)
{
case StreamEntityType.Control:
var control = strm.Entity as Control;
Console.WriteLine("Control URI: {0}", control.URL);
break;
case StreamEntityType.Delete:
var delete = strm.Entity as Delete;
Console.WriteLine("Delete - User ID: {0}, Status ID: {1}", delete.UserID, delete.StatusID);
break;
case StreamEntityType.DirectMessage:
var dm = strm.Entity as DirectMessage;
Console.WriteLine("Direct Message - Sender: {0}, Text: {1}", dm.Sender, dm.Text);
break;
case StreamEntityType.Disconnect:
var disconnect = strm.Entity as Disconnect;
Console.WriteLine("Disconnect - {0}", disconnect.Reason);
break;
case StreamEntityType.Event:
var evt = strm.Entity as Event;
Console.WriteLine("Event - Event Name: {0}", evt.EventName);
break;
case StreamEntityType.ForUser:
var user = strm.Entity as ForUser;
Console.WriteLine("For User - User ID: {0}, # Friends: {1}", user.UserID, user.Friends.Count);
break;
case StreamEntityType.FriendsList:
var friends = strm.Entity as FriendsList;
Console.WriteLine("Friends List - # Friends: {0}", friends.Friends.Count);
break;
case StreamEntityType.GeoScrub:
var scrub = strm.Entity as GeoScrub;
Console.WriteLine("GeoScrub - User ID: {0}, Up to Status ID: {1}", scrub.UserID, scrub.UpToStatusID);
break;
case StreamEntityType.Limit:
var limit = strm.Entity as Limit;
Console.WriteLine("Limit - Track: {0}", limit.Track);
break;
case StreamEntityType.Stall:
var stall = strm.Entity as Stall;
Console.WriteLine("Stall - Code: {0}, Message: {1}, % Full: {2}", stall.Code, stall.Message, stall.PercentFull);
break;
case StreamEntityType.Status:
var status = strm.Entity as Status;
Console.WriteLine("Status - @{0}: {1}", status.User.ScreenNameResponse, status.Text);
break;
case StreamEntityType.StatusWithheld:
var statusWithheld = strm.Entity as StatusWithheld;
Console.WriteLine("Status Withheld - Status ID: {0}, # Countries: {1}", statusWithheld.StatusID, statusWithheld.WithheldInCountries.Count);
break;
case StreamEntityType.TooManyFollows:
var follows = strm.Entity as TooManyFollows;
Console.WriteLine("Too Many Follows - Message: {0}", follows.Message);
break;
case StreamEntityType.UserWithheld:
var userWithheld = strm.Entity as UserWithheld;
Console.WriteLine("User Withheld - User ID: {0}, # Countries: {1}", userWithheld.UserID, userWithheld.WithheldInCountries.Count);
break;
case StreamEntityType.ParseError:
var unparsedJson = strm.Entity as string;
Console.WriteLine("Parse Error - {0}", unparsedJson);
break;
case StreamEntityType.Unknown:
default:
Console.WriteLine("Unknown - " + strm.Content + "\n");
break;
}
return await Task.FromResult(0);
}