Сталкиваясь с проблемами при создании чата в режиме реального времени с помощью API, flutter

#flutter #api #provider

Вопрос:

Привет, я разрабатываю приложение для чата в flutter, имеющее серверную часть sql. Веб-разработчики предоставили мне API для отправки и получения сообщений. Приложение работает нормально, проблема в том, что оно работает не в реальном времени, например, для отправки сообщения требуется время, и после этого мне приходится вручную вызывать состояние set, чтобы получить новое сообщение. Итак, есть ли какой-либо способ сделать чат реальным с помощью API в flutter?

Я пишу следующий код для реализации этого:

  Widget _getUI(BuildContext context) {
    return FutureProvider.value(
      value: _services.getUserMessages(
          context, widget.chatUserList.chatConnectionID),
      builder: (context, child) {
        print("Called");
        return Container(
          child: context.watch<List<MessagesModel>>() == null
              ? LoadingWidget()
              : Column(
                  children: [
                    Expanded(
                      child: Container(
                        child: ListView.builder(
                            controller: _scrollController,
                            itemCount:
                                context.watch<List<MessagesModel>>().length,
                            itemBuilder: (context, i) {
                              Timer(
                                  Duration(milliseconds: 300),
                                  () => _scrollController.animateTo(
                                      _scrollController
                                          .position.maxScrollExtent,
                                      duration: Duration(milliseconds: 700),
                                      curve: Curves.ease));
                              return Padding(
                                padding:
                                    const EdgeInsets.symmetric(vertical: 2.0),
                                child: MessageTile(
                                  message: context
                                      .watch<List<MessagesModel>>()[i]
                                      .textMessage,
                                  sendByMe: context
                                          .watch<List<MessagesModel>>()[i]
                                          .chatReceiverTypeId !=
                                      userModel.patientID,
                                  time: context
                                      .watch<List<MessagesModel>>()[i]
                                      .createdDate,
                                ),
                              );
                            }),
                      ),
                    ),
                    Container(
                      alignment: Alignment.bottomCenter,
                      width: MediaQuery.of(context).size.width,
                      color: Colors.white,
                      child: Container(
                        padding:
                            EdgeInsets.symmetric(horizontal: 24, vertical: 10),
                        child: Row(
                          children: [
                            Expanded(
                                child: TextField(
                              style:
                                  TextStyle(color: Colors.black, fontSize: 13),
                              controller: messageController,
                              onChanged: (val) {
                                setState(() {});
                              },
                              decoration: InputDecoration(
                                  hintText: "Type Here...",
                                  hintStyle: TextStyle(
                                    color: Colors.black,
                                    fontSize: 13,
                                  ),
                                  focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide.none),
                                  border: OutlineInputBorder(
                                      borderSide: BorderSide.none)),
                            )),
                            SizedBox(
                              width: 16,
                            ),
                            IconButton(
                              onPressed: () async {
                                if (messageController.text.isEmpty) {
                                  return;
                                }
                                Timer(
                                    Duration(milliseconds: 300),
                                    () => _scrollController.animateTo(
                                        _scrollController
                                            .position.maxScrollExtent,
                                        duration: Duration(milliseconds: 700),
                                        curve: Curves.ease));
                                await _services.createMessage(context,
                                    model: MessageComposerModel(
                                        senderId: userModel.patientID,
                                        senderTypeId: 2,
                                        message: messageController.text,
                                        receiverId:
                                            widget.chatUserList.doctorID,
                                        receiverTypeId: 1,
                                        chatConnectionId: widget
                                            .chatUserList.chatConnectionID,
                                        lastInsertedMessageID: 0));
                                if (Provider.of<AppState>(context,
                                            listen: false)
                                        .getStateStatus() ==
                                    AppCurrentState.IsFree) {
                                  messageController.clear();
                                }
                                setState(() {});
                              },
                              icon: Icon(
                                Icons.send,
                                color: messageController.text.isEmpty
                                    ? Colors.grey
                                    : Colors.black,
                              ),
                            )
                          ],
                        ),
                      ),
                    )
                  ],
                ),
        );
      },
    );
  }
 

И вызов моих служб выглядит так:

   Future<void> createMessage(BuildContext context,
      {MessageComposerModel model, String authToken}) async {
    try {
      return await http.post(
        Uri.parse(BackendConfigs.apiBaseUrl   "/api/Chat/SendChatMessage"),
        body: json.encode(model.toJson()),
        headers: {
          'Authorization': 'Bearer $authToken',
          'Content-Type': 'application/json'
        },
      ).then((response) {
        if (response.statusCode == 201 || response.statusCode == 200) {
          Provider.of<AppState>(context, listen: false)
              .stateStatus(AppCurrentState.IsFree);
          print(response.body);
          // return SuccessResponseModel.fromJson(json.decode(response.body));
        } else {
          Provider.of<AppState>(context, listen: false)
              .stateStatus(AppCurrentState.IsFree);
          Provider.of<ErrorString>(context, listen: false)
              .saveErrorString(response.reasonPhrase);
        }
      });
    } on HttpException catch (e) {
      Provider.of<AppState>(context, listen: false)
          .stateStatus(AppCurrentState.IsError);
      Provider.of<ErrorString>(context, listen: false)
          .saveErrorString(e.message);
      rethrow;
    }
  }
 

Комментарии:

1. Ищите розетки

2. могу ли я также использовать signalr_client для этого?

3. вместо будущего используйте streambuilder. Узнайте об этом