Chat multi threads

Galera estou desenvolvendo um chat bot, a questão com a resposta que o bot dá está tudo certo, o meu problema é quando mais de uma pessoa entra em contato com o chat, ele está tratando como se ambos fosse um só, eu acredito que o problema está na forma que eu estou tratando as requisições que o usuário faz.

essa é a minha managedBeam

    public String submit(){
		System.out.println("====submit======");

		getInteracoes().add(new InteracaoChat(1, userInput,Util.dataFormatada()));
		//realiza interaçao com o chat
		setBotOutput(new RealizaPerguntBot().realizaPergunta(userInput));

		return "";
	}


public class RealizaPerguntBot {
	/**
	 * metodo responsavel por criar conexao com o watson e devolver uma resposta adequada para a pergunta realizada
	 * 
	 * @param pergunta
	 * @return resposta
	 */
	
	/**
	 * O contexto é onde a conversa está no momento da interação, o contexto inicia como nulo pois é o inicio da conversa, a medida que vai 
	 * encaminhando a conversa o contexto irá recebendo um novo valor, caso assumir nulo novamente a conversa irá voltar ao inicio
	 */
	static Map<String, Object> context =  null;

	public String realizaPergunta(String pergunta){
//		
	    /**
	     * Service é uma classe nativa do watson, recebe a data (versão) do conversation
	     */
		ConversationService service = new ConversationService(ConstantesWatson.DATE_VERSION_CONVERSATION);
		
		/*
		 * configura o servico, recebe o usuario e a senha 
		 * */
		service.setUsernameAndPassword(ConstantesWatson.USER_NAME_CONVERSATION, ConstantesWatson.PASSWORD_CONVERSATION);

		/**
		 * newMesage é ai que será feito a interação do usuário com o bot, é passado a pergunta(interação) que o usuário fez ao bot, é passado o contexto
		 * para que o bot saiba onde a conversa parou
		 */
		MessageRequest newMessage = new MessageRequest.Builder().inputText(pergunta).context(context).build();
		
		
		
		String workspaceId = ConstantesWatson.WORKSPACE_ID_CONVERSATION;
		/**
		 * Response recebe a resposta do bot com base na pergunta feita, é necessário passar o worksapeceid e a pergunta realizada pelo usuario
		 */
		MessageResponse response = service.message(workspaceId, newMessage).execute();
		//recebe o novo valor do contexto.
		context = response.getContext();
		
		
	
		return new TrataRespostaJson().trataResponstaJson(response.toString());
	}

Gostaria de saber de vocês como eu faria para solucionar esse problema, se a implementação de threads resolveria o problema, caso seja isso, me indique uma forma mais adequada para fazer.

Grato

O context está static, então acredito que irá compartilhar com todos os usuários. Se remover o static, ficará um context por sessão se o managedBeam for sessionScope, resolvendo o problema de compartilhamento.

Supondo que informações poderiam ser compartilhadas entre usuários, então seria melhor que o context seja um singleton, mas seria necessário criar uma forma de identificação para que o bot diferencie cada usuário. Não acho que este seja o caso já que o context fica nulo quando a conversa termina.

1 curtida

Diego12, o contexto eu coloquei como estatico para que nas próximas interações do usuário o bot saiba onde a conversa está, caso eu tire o estático cada interação que o usuário fizer com o bot, o bot irá interpretar como se fosse o inicio da conversa sendo assim nunca irá dar continuidade na conversa, coloquei como estatico e resolveu esse problema porém atende a apenas um usuário.

Se vc colocar o managedBem como sessionScope, vc terá uma instancia para cada usuário e não misturaria.

Vc poderia usar um singleton:

public enum ContextManager {

    INSTANCE;

    private Map<String, Map<String, Object>> contexts;

    private ContextManager() {
        contexts = new HashMap<>();
    }

    public Map<String, Object> getContext(String user) {
        Map<String, Object> context = contexts.get(user);
        if (context == null) {
            // inicia
            context = new HashMap<>();
            contexts.put(user, context);
        }
        return context;
    }

    public void updateContext(String user, Map<String, Object> context) {
        contexts.put(user, context);
    }

    public void disposeContext(String user) {
        contexts.remove(user);
    }
}

usaria assim:

String user;
// iniciar ou continuar
Map<String, Object> context = ContextManager.INSTANCE.getContext(user);
// finalizar
ContextManager.INSTANCE.disposeContext(user);
// atualizar
ContextManager.INSTANCE.updateContext(user, context);