You can compare the input string to a pattern.
#!/bin/bash
while true; do
    read -p 'Enter 3 numbers separated by comma' -r text
    case $text in
     *[!,0-9]* | *,*,*,* | ,*,* | *,*, ) ;;
     *,*,* ) break;;
    esac
    echo invalid
done
Your processing will be much easier if you require whitespace instead of commas between the values, though.
#!/bin/bash
while true; do
    read -p 'Enter 3 numbers separated by space' -r first second third
    case $first,$second,$third in
     *[!,0-9]* | *,*,*,* | ,*,* | *,*, ) ;;
     *,*,* ) break;;
    esac
    echo invalid
done
In brief, each expression between | up to ) is examined like a glob pattern (what you use for file name wildcards, like *.png or ?.txt); the subpattern [!abc] matches a single character which is not a, b, or c; these consecutive characters can also be expressed as a range [!a-c].
So, we reject anything which contains a character which isn't a number or a comma, anything with too many commas, anything with commas at the edges, and (implicitly, by falling through) anything with too few commas.