質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • JavaScript

    17065questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Java

    14142questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • HTML

    9317questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • JSP

    948questions

    JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

  • WebSocket

    173questions

    WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

【WebSocket】JavaとJavaScriptで相互でやりとりをおこないたい

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 866

Sfidante

score 90

WebSocketを利用して
1対1でのメッセージのやりとりをおこなうプログラムを作っています。
しかし、
不具合がでていて解決策に困っているので、
お力添えよろしくお願いいたします。

何をおこないたいかと申しますと、
メッセージを受信した時にuseridが自分のものか相手のものかを判別して、
自分のuseridだった場合の表示の仕方と
相手のuseridだった場合の表示の仕方を変えていく処理をしたいです。

そのためにまずはonMessage()の時に自分のuseridをクライアント側にわからせるためのコードを知りたです。


問題となるJSPのソースコードを記載いたします。
<div class="message_box c-center__margin">
            <ul id="message-list">
                <c:forEach var="messagelist" items="${ requestScope.messageList }">
                <c:if test="${ messagelist.userid == myuserid }" var="my"/>
                <c:if test="${ !my }">
                <li class="msg_recieve">
                    <a href="" target="_blank">
                    <img src="<c:out value='${ UserProfile.photo }'/>" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini">
                    </a>
                    <div class="inner-box2">
                    <p class="balloon_left">${ messagelist.message }</p>
                    </div>
                </li>
                    <p class="time_recieve"><time datetime="2015-07-11T11:11">
                    <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                    </time></p>
                </c:if>
                <c:if test="${ my }">
                <li class="msg_send">
                    <div class="inner-box">
                         <p class="balloon_right" id="messageArea">${ messagelist.message }</p>
                    </div>
                </li>
                        <p class="time_send">
                        <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                        </p>
                </c:if>
                </c:forEach>
            </ul>
        </div>
        
        <div class="message_inner_box c-center__margin">
        <div class="c-center message-area">
            <input type="text" id="messageInput" class="p-sendbox" name="sendarea" maxlength="1000" style="width:500px;height:100px;">
            <p>※<a href="">同意事項</a>に同意の上、送信してください。</p>
            <a href="javascript:;" class="c-btn_chenge" onclick="window.onload();" id="messageInput"><img src="image/images/send_btn_03.png" alt="送信ボタン" class="p-message_send"></a>
        </div>
    </div>

自分と相手のuseridで表示形式を変えようとしています。
そして、JavaScriptを下記に示します。
    var webSocket;
    window.onload = function() {
        var forRtoA = document.createElement('a');
        forRtoA.href = "loadMessage";
        webSocket = new WebSocket(forRtoA.href.replace("http://", "ws://").replace("https://", "wss://"));
        var messageArea = document.getElementById("message-list");
        
        var appendMessage = function(value, color) {
            var messageElement = document.createElement("messageArea");
            var time = new Date();
            var month = time.getMonth() + 1;
            if(month < 10) { month = "0" + month; }
            var day = time.getDate();
            if(day < 10) { day = "0" + day; }
            var hour = time.getHours();
            if(hour < 10) { hour = "0" + hour; }
            var minute = time.getMinutes();
            if(minute < 10) { minute = "0" + minute; }
            var now = month + "/" + day + " " + hour + ":" + minute;
            messageElement.innerHTML = '<li class="msg_send"><div class="inner-box"><p class="balloon_right" id="messageArea">' + value + '</p></div></li><p class="time_send">' + now + '</p>';
            messageArea.appendChild(messageElement);
        }
        
        webSocket.onmessage = function(message) {
            var data = JSON.parse(message.data);
            if ("message" == data.command) {
                appendMessage(data.text, "black");
            } else if ("error" == data.command) {
                appendMessage(data.text, "red");
            }
        }
        
        var messageInput = document.getElementById("messageInput");
        messageInput.onkeypress = function(e) {
            if (13 == e.keyCode) {
                var message = messageInput.value;
                if (webSocket && "" != message) {
                    webSocket.send(message);
                    messageInput.value = "";
                }
            }
        }
    }
最初は一人のユーザーだけのことしか考えておらず、
相手が入力した文章も自分が書いたような表示になってしまいます。

そして、肝心となるJavaのソースコードを下記に記します。
//相手が誰かを紐付けするroomidを取得してそれを一時的にセッションに関連付けてデータベースに保存します
ses.removeAttribute("roomid");
String sessionid = ses.getId();
int roomid = messagedao.selectRoomID(myuserid, youruserid).getRoomid();
ses.setAttribute("roomid", roomid);
messagedao.deletSessionID(myuserid);
messagedao.insertSessionID(sessionid, myuserid, roomid);

//上記の処理を受けてセッションでもって、メッセージのやりとりを管理しています
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import dao.MessageDao;

@ServerEndpoint(value = "/loadMessage" , configurator = GetHttpSessionConfigurator.class)
public class WebSocketEndpointAction{
    public static List<Session> sessions = new ArrayList<Session>();
    private HttpSession httpSession;
    private String sessionid;
    
    @OnOpen
    public void onOpen(Session session , EndpointConfig config) {
        // 開始時
        sessions.add(session);
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        sessionid = httpSession.getId();
    } 
    

    @OnMessage
    public  void onMessage(String message , EndpointConfig config) throws IOException, ServletException {
        // クライアントからの受信時
        for (Session session : sessions) {
            session.getBasicRemote().sendText("{\"command\":\"message\", \"text\": \"" + message.replace("\\", "\\\\").replace("\"", "\\\"") + "\"}");
             MessageDao messagedao = new MessageDao();
                try{
                    messagedao.connect();
                    int userid = messagedao.selectSessionID(sessionid).getUserid();
                    int roomid = messagedao.selectSessionID(sessionid).getRoomid();
                    messagedao.insertMessage(userid, roomid, message);
                    messagedao.close();
                }catch(Exception e){
                    e.printStackTrace();
                }
        }
    }

@OnError
    public void onError(Throwable t) throws IOException {
        // エラー発生時
        for (Session session : sessions) {
            session.getBasicRemote().sendText("{\"command\":\"error\", \"text\": \"" + t.getMessage().replace("\\", "\\\\").replace("\"", "\\\"") + "\"}");
        }
    }

    

    @OnClose
    public void onClose(Session session) {
        // 完了時
        sessions.remove(session);
    }
}
何卒よろしくお願いいたします。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

サーバーサイドのsession.getBasicRemote().sendTextにuseridを含めてやれば、クライアントサイドのJavascriptでuseridが自身のユーザーIDかどうか判定できると思います。

サーバーサイドのonMessageですべてのsessionに対して、ブロードキャスト送信していますが、自分以外で同じルームの場合、メッセージを送信するような処理にした方がいいかと。。
(自分が送信したメッセージを自分も受信するというのは無駄な通信になるので。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    【Python】マルチバイト文字の表示方法

    昨日、Pythonのマルチバイト文字の表示方法について、質問した者です。 https://teratail.com/questions/9408 その時は、ご回答頂いた通り、 # 

  • 受付中

    websocket実装方法

    websocketを使ってチャットを作成したいです。 IDEはNetBeansを使用しています。 実装方法を詳しく教えてください。

  • 解決済

    【WebSocket】セッションIDをJavaで取得したい

    WebSocketを用いて、 1対1でのメッセージのやりとりをおこなっておりますが、 メッセージを送ったのが、 自分なのか相手なのかの区別の付け方がわからず困っています。 イメー

  • 解決済

    【JavaScript】メッセージのやりとりの処理について

    WebSocketとJavaScriptを用いて即時性のあるメッセージのやりとりをおこなう プログラムを書いているのですが、 数カ所、動作がおかしいところがあるので、 ご享受いただ

  • 受付中

    【JavaScript】テキストエリアに改行して入力した文字列が表示できない

    テキストエリアに改行して文字を入力して 改行された状態で違う箇所へ表示させたいのですが、 改行処理がうまくいかずに まったく表示できない状況です。 このメッセージをMySQLへ保

  • 受付中

    JavaScriptの時刻を更新したい

    下記のコードは時刻を取っているのですがこれをデジタル時計みたいにほっておいても時間が変わっているという風にするにはどうすればいいですか? <!doctype html> <html

  • 解決済

    javascriptのsetTimeoutを使って表示したい

    <!doctype html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=devic

  • 解決済

    java 日付の取得と変更について

    javaの日付の取得と変更に関するコードについて質問です 参考書のとおりに、下記のコードを書いて実行してみたのですが 実行してみても、現在の日付から5日後の日付が出力されず、現在

同じタグがついた質問を見る

  • JavaScript

    17065questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Java

    14142questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • HTML

    9317questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • JSP

    948questions

    JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

  • WebSocket

    173questions

    WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。