
官方的团结SDK进行流聊天。
网站|教程| SDK文档|注册API密钥

Stream Chat SDK是官方的统一SDK,用于流聊天,这是用于构建聊天以及消息传递游戏和应用程序的服务。
支持IL2CPP
支持WebGL
大多数方面和爱好项目都是免费的。您可以免费使用少于五个团队成员的流聊天聊天,每月收入不超过10,000美元。访问我们的网站并申请制造商帐户。
.unitypackage查看我们有关如何设置项目并执行基本操作的教程。
在StreamChat/SampleProject文件夹中,您会找到一个完整工作的聊天示例:

由Unity的UGUI UI系统创建,并支持旧版和新Unity的输入系统。
StreamChat/SampleProject/Config/DemoCredentials.assetStreamChat/SampleProject/Scenes/ChatDemo.scene和hit Play如何启用Unity的新输入系统?
Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform.
您可以删除[email protected]目录。但是请注意,Unity的纽顿夫人的包裹具有IL2CPP支持。如果您想替换它并仍然使用IL2CPP,请确保您选择的JSON实施也支持IL2CPP。
这里有一些快速的代码示例可以让您入门。有关详细信息,请查看我们的文档
StreamChatClient允许您根据提供的条件与流聊天服务器,创建频道,查询频道,用户和成员连接的主要聊天管理器StreamChannel - 对话中的频道组用户。根据您的设置,用户可能需要加入频道作为会员以发送消息StreamUser代表应用程序中的一个用户StreamChannelMember代表特定频道成员的用户的对象。此对象包含属性member.User可以访问用户对象StreamMessage - 表示通道内的一条消息用户the StreamChatClient.CreateDefaultClient();创建IStreamChatClient实例的工厂方法:
public class ChatManager : MonoBehaviour
{
public IStreamChatClient Client { get ; private set ; }
protected void Awake ( )
{
Client = StreamChatClient . CreateDefaultClient ( ) ;
}
}最简单的启动方法是启用开发人员授权并与客户端生成的auth令牌建立联系:
var userId = StreamChatClient . SanitizeUserId ( "user-name" ) ;
var userToken = StreamChatClient . CreateDeveloperAuthToken ( userId ) ;
// Replace API_KEY with your Api Key from the Stream Dashboard
var localUserData = await Client . ConnectUserAsync ( "API_KEY" , userId , userToken ) ;等待服务器响应的每个功能您都可以使用C#Modern async/等待语法来调用或附加.AsCallback() ,并用作经典回调,如下所示:
Client . ConnectUserAsync ( "API_KEY" , userId , userToken )
. AsCallback ( onSuccess : result =>
{
var localUserData = result ;
} , onFailure : exception =>
{
Debug . LogException ( exception ) ;
} ) ; .AsCallback()方法接受两个委托: Action<TResponse> onSuccess和Action<Exception> onFailure ,您可以用来对成功和错误响应案例做出反应。相反,Lambda回调您还可以提供与下面示例相同的签名的方法:
public void ConnectUser ( )
{
var userId = StreamChatClient . SanitizeUserId ( "user-name" ) ;
var userToken = StreamChatClient . CreateDeveloperAuthToken ( userId ) ;
Client . ConnectUserAsync ( "API_KEY" , userId , userToken )
. AsCallback ( OnUserConnected , OnUserConnectionFailed ) ;
}
private void OnUserConnected ( IStreamLocalUserData localUserData )
{
Debug . Log ( "User connected: " + localUserData . User . Name ) ;
}
private void OnUserConnectionFailed ( Exception exception )
{
Debug . LogException ( exception ) ;
}我们强烈建议使用async/await语法建议,如以下示例,您会注意到,该代码使代码更加简单,更易于阅读和维护。
连接后,您可以开始使用频道,以便用户可以发送消息。
有两种创建渠道的方法:
有关用户可以加入的预定义渠道。这对于用户可以加入或离开的任何通用渠道或氏族,俱乐部和团体都非常有用。
var channel = await Client . GetOrCreateChannelWithIdAsync ( ChannelType . Messaging , "my-channel-id" ) ;或带回调:
Client . GetOrCreateChannelWithIdAsync ( ChannelType . Messaging , "my-channel-id" )
. AsCallback ( channel =>
{
Debug . Log ( $ "Channel { channel . Id } created successfully" ) ;
} , exception =>
{
Debug . LogException ( exception ) ;
} ) ; 非常适合公共或私人组消息,组中的用户顺序无关紧要,因此每当用户使用此方法连接用户时,他们将始终看到他们的聊天历史记录:
var channel = await Client . GetOrCreateChannelWithMembersAsync ( ChannelType . Messaging , users ) ;浏览通过某些条件过滤的所有通道或通道使用Client.QueryChannelsAsync
var filters = new IFieldFilterRule [ ]
{
ChannelFilter . Cid . In ( "channel-cid" , "channel-2-cid" , "channel-3-cid" )
} ;
var sort = ChannelSort . OrderByAscending ( ChannelSortFieldName . CreatedAt ) ;
var channels = await Client . QueryChannelsAsync ( filters , sort ) ;过滤机制非常强大,可以使您合并多个规则。您可以在此处查看可用于频道查询的可用字段和操作员的完整列表。
// Each operator usually supports multiple argument types to match your needs
ChannelFilter . Cid . EqualsTo ( "channel-cid" ) ; // string
ChannelFilter . Cid . EqualsTo ( channel ) ; // IStreamChannel
ChannelFilter . Cid . In ( "channel-cid" , "channel-2-cid" , "channel-3-cid" ) ; // Comma separated strings
var channelCids = new List < string > { "channel-1-cid" , "channel-2-cid" } ;
ChannelFilter . Cid . In ( channelCids ) ; // Any collection of string var filters = new IFieldFilterRule [ ]
{
ChannelFilter . CreatedById . EqualsTo ( Client . LocalUserData . User )
} ; var filters = new IFieldFilterRule [ ]
{
ChannelFilter . MembersCount . GreaterThan ( 10 )
} ; var weekAgo = DateTime . Now . AddDays ( - 7 ) . Date ;
var filters = new IFieldFilterRule [ ]
{
ChannelFilter . CreatedAt . GreaterThan ( weekAgo )
} ; var dayAgo = DateTime . Now . AddHours ( - 24 ) ;
var filters = new IFieldFilterRule [ ]
{
ChannelFilter . UpdatedAt . GreaterThan ( dayAgo )
} ;消息可通过channel.Messages属性访问,其中包含最新消息的收集。因为在频道历史记录中可能会有数千条消息, channel.Messages集合只包含最新消息。您可以通过调用channel.LoadOlderMessagesAsync()来加载旧消息,该消息将加载历史记录的其他部分。一种常见的方法是调用channel.LoadOlderMessagesAsync() ,每当用户击中消息的末尾滚动视图时,只有在用户实际想查看它们时,您才会加载较旧的消息。您可以在示例项目的messagelistview.cs中看到此方法的示例
var sentMessage = await channel . SendNewMessageAsync ( "Hello" ) ; var messageInThread = await channel . SendNewMessageAsync ( new StreamSendMessageRequest
{
ParentId = parentMessage . Id , // Write in thread
ShowInChannel = false , // Optionally send to both thread and the main channel like in Slack
Text = "Hello" ,
} ) ; var messageWithQuote = await channel . SendNewMessageAsync ( new StreamSendMessageRequest
{
QuotedMessage = quotedMessage , // Reference to IStreamMessage
Text = "Hello" ,
} ) ;无声消息不会触发频道成员的事件。通常用于系统消息
var silentMessage = await channel . SendNewMessageAsync ( new StreamSendMessageRequest
{
Text = "System message" ,
Silent = true
} ) ; await message . PinAsync ( ) ; await message . PinAsync ( new DateTime ( ) . AddDays ( 7 ) ) ; // Pin for 7 days await message . UnpinAsync ( ) ; await message . UpdateAsync ( new StreamUpdateMessageRequest
{
Text = "New changed message" ,
} ) ; await message . UpdateAsync ( new StreamUpdateMessageRequest
{
CustomData = new StreamCustomDataRequest
{
{ "CategoryId" , 12 } ,
{ "Awards" , new string [ ] { "Funny" , "Inspirational" } }
}
} ) ;仅清除文本,但留下其他相关数据,反应,线程子消息等。完整
await message . SoftDeleteAsync ( ) ; 完全删除消息并删除与此消息有关的所有数据
await messageInChannel . HardDeleteAsync ( ) ; await message . SendReactionAsync ( "like" ) ; await message . SendReactionAsync ( "clap" , 10 ) ; await message . SendReactionAsync ( "love" , enforceUnique : true ) ; await message . DeleteReactionAsync ( "like" ) ; // Get file byte array however you want e.g. Addressables.LoadAsset, Resources.Load, etc.
var sampleFile = File . ReadAllBytes ( "path/to/file" ) ;
var fileUploadResponse = await channel . UploadFileAsync ( sampleFile , "my-file-name" ) ;
var fileWebUrl = fileUploadResponse . FileUrl ; var sampleImage = File . ReadAllBytes ( "path/to/file" ) ;
var imageUploadResponse = await channel . UploadImageAsync ( sampleFile , "my-image-name" ) ;
var imageWebUrl = imageUploadResponse . FileUrl ; var channel = await Client . GetOrCreateChannelWithIdAsync ( ChannelType . Messaging , channelId : "my-channel-id" ) ;
await channel . DeleteFileOrImageAsync ( "file-url" ) ;每当发生任何更改(新消息,反应等)时,频道对象将自动更新。您可以通过订阅IStreamChannel暴露事件来应对这些变化:
channel . MessageReceived += OnMessageReceived ;
channel . MessageUpdated += OnMessageUpdated ;
channel . MessageDeleted += OnMessageDeleted ;
channel . ReactionAdded += OnReactionAdded ;
channel . ReactionUpdated += OnReactionUpdated ;
channel . ReactionRemoved += OnReactionRemoved ; var localUserData = Client . LocalUserData ;
var localUser = localUserData . User ;StreamUser的实例 var users = await Client . QueryUsersAsync ( ) ; var users = await Client . QueryUsersAsync ( new Dictionary < string , object > ( )
{
{
"id" , new Dictionary < string , object >
{
{ "$eq" , otherUserId }
}
}
} ) ;
var otherUser = users . First ( ) ; var filters = new Dictionary < string , object >
{
{
"id" , new Dictionary < string , object >
{
{
"$in" , listOfUserIds
}
}
}
} ;
var users = await Client . QueryUsersAsync ( filters ) ;在支持的查询参数和操作员上了解更多信息
根据您的应用程序配置,用户可能需要以成员的身份加入频道,以发送消息或查看其他用户消息
// Multiple overloads available depending on your needs
await channel . AddMembersAsync ( user ) ; // instance of IStreamUser
await channel . AddMembersAsync ( user1 , user1 ) ; // Multiple instances of IStreamUser
await channel . AddMembersAsync ( listOfUsers ) ; // List<IStreamUser>
await channel . AddMembersAsync ( "user-id" ) ; // string ID
await channel . AddMembersAsync ( listOfUserIds ) ; // List<string> that contains IDs // Multiple overloads available depending on your needs
await channel . RemoveMembersAsync ( member ) ; // instance of IStreamChannelMember
await channel . RemoveMembersAsync ( member1 , member2 ) ; // Multiple instances of IStreamChannelMember
await channel . RemoveMembersAsync ( listOfMembers ) ; // List<IStreamChannelMember>
await channel . RemoveMembersAsync ( user ) ; // instance of IStreamUser
await channel . RemoveMembersAsync ( user1 , user1 ) ; // Multiple instances of IStreamUser
await channel . RemoveMembersAsync ( listOfUsers ) ; // List<IStreamUser>
await channel . RemoveMembersAsync ( "user-id" ) ; // string ID
await channel . RemoveMembersAsync ( listOfUserIds ) ; // List<string> that contains IDsStream提供了所有必要的工具和功能,以正确管理大型社区。
标记意味着将将此用户或消息报告给聊天适度。聊天管理员和主持人可以在仪表板中查看报告的用户和消息。
await user . FlagAsync ( ) ; await message . FlagAsync ( ) ; await channel . BanUserAsync ( user ) ; await channel . BanUserAsync ( user , "You got banned for 2 hours for toxic behaviour." , 120 ) ; 禁止IP有助于防止用户创建一个新帐户以绕过禁令的情况。
await channel . BanUserAsync ( user , timeoutMinutes : 120 , isIpBan : true ) ; await channel . BanUserAsync ( user , "You got banned for 2 hours for toxic behaviour." , 120 ) ; var request = new StreamQueryBannedUsersRequest
{
CreatedAtAfterOrEqual = new DateTimeOffset ( ) . AddHours ( - 24 ) ,
Limit = 30 ,
Offset = 0 ,
} ;
var bannedUsersInfo = await Client . QueryBannedUsersAsync ( request ) ;Shadow禁止的用户不知道他被禁止。有时这很有用,因为用户需要更多时间才能意识到他被禁止的。
StreamUser await channel . ShadowBanUserAsync ( user ) ; StreamChannelMember await channel . ShadowBanMemberAsync ( channelMember ) ; await user . MuteAsync ( ) ; await user . UnmuteAsync ( ) ; await channel . MuteChannelAsync ( ) ; await channel . UnmuteChannelAsync ( ) ;上面的示例只有许多示例 - 查看我们的完整文档,以获取更多洞察力和示例
继续并向您的请求打开GitHub问题,我们将尽快做出回应。
接触我们的支持。
我们最近关闭了3800万美元的B系列资金回合,我们一直在积极发展。我们的API被超过十亿的最终用户使用,您将有机会对全球最强大的工程师团队中的产品产生巨大影响。查看我们当前的开口,并通过Stream的网站申请。